ECMAScript® 2024 语言规范

关于本规范

https://tc39.es/ecma262/ 上的文档是最准确和最新的ECMAScript规范。它包含了最新年度快照的内容以及任何已完成的提案(那些在提案流程中达到第4阶段并因此在多个实现中实现且将在下一次实际修订中包含的提案)自该快照以来的内容。

本文档可以作为单页多页查看。

为此规范做贡献

此规范在GitHub上由ECMAScript社区的帮助下开发。有多种方式可以为此规范的发展做出贡献:

有关如何创建此文档的更多信息,请参阅colophon

导言

此ecma标准定义了ECMAScript 2024语言。它是ECMAScript语言的第十五版 规范。自1997年第一版出版以来,ECMAScript已发展成为世界上 最广泛使用的通用编程语言。它最为人所知的是嵌入在网络中的语言 浏览器,但也被广泛用于服务器和嵌入式应用程序。

ECMAScript基于几种原始技术,最著名的是JavaScript(Netscape)和 JScript(微软)。该语言由Netscape的Brendan Eich发明,首次出现在该公司的 Navigator 2.0浏览器。它已出现在Netscape的所有后续浏览器和Netscape的所有浏览器中 Microsoft从Internet Explorer 3.0开始。

ECMAScript语言规范的开发始于1996年11月。这个的第一版 ECMA标准于1997年6月由ECMA大会通过。

该ECMA标准已提交给ISO/IEC JTC 1以供快速通道程序采用,并被批准为 国际标准ISO/IEC 16262,1998年4月。ECMA大会于1998年6月批准了第二个 ECMA-262版本,使其完全符合ISO/IEC 16262。第一个和第二个之间的变化 版本本质上是编辑性的。

标准第三版引入了强大的正则表达式、更好的字符串处理、新的控件 语句、try/catch异常处理、更严格的错误定义、数字输出的格式和次要 对未来语言增长的预期变化。ECMAScript标准的第三版被 1999年12月的ECMA大会,并于2002年6月作为ISO/IEC 16262:2002发布。

第三版发布后,ECMAScript与全球广泛采用 Web,它已成为基本上所有Web浏览器都支持的编程语言。重要的 开发ECMAScript第四版的工作已经完成。然而,这项工作没有完成,也没有出版 作为ECMAScript的第四版,但其中一些被纳入了第六版的开发。

ECMAScript第五版(作为ECMA-262 5th版发布)事实上已编纂 对浏览器实现中常见的语言规范的解释并添加了 支持自第三版出版以来出现的新功能。这些功能包括 访问器 属性,对象的反射创建和检查,属性的程序控制 属性,额外的数组操作功能,支持JSON对象编码格式,以及严格的 提供增强错误检查和程序安全性的模式。第五版被ECMA2009年12月大会采用。

第五版提交给ISO/IEC JTC 1采用快速通道程序,并被批准为国际标准ISO/IEC 16262:2011。ECMAScript标准的5.1版包含了一些小的修正,文本与ISO/IEC 16262:2011相同。5.1版于2011年6月被Ecma大会采纳。

第六版的集中开发始于2009年,当时第五版正在准备出版。然而,在此之前,自1999年第三版发布以来,已经进行了大量的实验和语言增强设计工作。从某种意义上说,第六版的完成是十五年努力的结晶。本版的目标包括提供对大型应用程序、库创建的更好支持,并将ECMAScript用作其他语言的编译目标。其主要增强功能包括模块、类声明、词法块作用域、迭代器和生成器、用于异步编程的Promises、解构模式和正确的尾调用。ECMAScript内置库扩展了对附加数据抽象的支持,包括地图、集合和二进制数值数组,并在字符串和正则表达式中增加了对Unicode补充字符的支持。内置库还通过子类化变得可扩展。第六版为常规的、增量的语言和库增强提供了基础。第六版于2015年6月被大会采纳。

ECMAScript 2016是Ecma TC39在新的年度发布节奏和开放开发流程下发布的第一个ECMAScript版本。从ECMAScript 2015源文档生成了一个纯文本源文档,作为在GitHub上进一步开发的基础。在这一标准的开发过程中,提交了数百个拉取请求和问题,代表了成千上万个错误修复、编辑修正和其他改进。此外,还开发了许多软件工具来帮助这一工作,包括Ecmarkup、Ecmarkdown和Grammarkdown。ES2016还包括对新幂运算符的支持,并在Array.prototype中添加了一个名为includes的新方法。

ECMAScript 2017引入了异步函数、共享内存和原子操作,以及一些较小的语言和库增强、错误修复和编辑更新。异步函数通过提供Promise返回函数的语法来改进异步编程体验。共享内存和原子操作引入了一种新的内存模型,允许多代理程序使用原子操作进行通信,即使在并行CPU上也能确保定义明确的执行顺序。它还包括Object上的新静态方法:Object.valuesObject.entriesObject.getOwnPropertyDescriptors

ECMAScript 2018通过AsyncIterator协议和异步生成器引入了对异步迭代的支持。它还包括四个新的正则表达式特性:dotAll标志、命名捕获组、Unicode属性转义和后行断言。最后,它还包括对象的剩余和扩展属性。

ECMAScript 2019引入了一些新的内置函数:Array.prototype上的flatflatMap用于扁平化数组,Object.fromEntries用于直接将Object.entries的返回值转化为新对象,以及String.prototype上的trimStarttrimEnd作为更好命名的替代方案,取代广泛实现但非标准的String.prototype.trimLefttrimRight内置函数。此外,它还包括一些语法和语义的较小更新。更新的语法包括可选的catch绑定参数,并允许在字符串字面量中使用U+2028(行分隔符)和U+2029(段落分隔符)以与JSON保持一致。其他更新包括要求Array.prototype.sort为稳定排序,要求JSON.stringify无论输入如何都返回格式良好的UTF-8,以及通过要求Function.prototype.toString返回相应的原始源文本或标准占位符来进行明确。

ECMAScript 2020,第11版,引入了字符串的matchAll方法,用于生成全局正则表达式匹配对象的迭代器;import()语法,用于动态异步导入模块;BigInt,一种新的数字原始类型,用于处理任意精度的整数Promise.allSettled,一种新的Promise组合器,不会短路;globalThis,一种通用的全局this值访问方式;专用的export * as ns from 'module'语法,用于模块内;增加了for-in枚举顺序的标准化;import.meta,一个由宿主填充的对象,包含关于模块的上下文信息;以及为处理“nullish”值(undefinednull)引入的两个新语法特性:nullish合并,一个值选择操作符;以及可选链,一个属性访问和函数调用操作符,当要访问/调用的值为nullish时会短路。

ECMAScript 2021,第12版,引入了字符串的replaceAll方法;Promise.any,一个在输入值被实现时短路的Promise组合器;AggregateError,一种新错误类型,用于同时表示多个错误;逻辑赋值操作符(??=&&=||=);WeakRef,用于引用目标对象而不保留其免于垃圾回收,以及FinalizationRegistry,用于管理在目标对象被垃圾回收时执行的清理操作的注册和取消注册;数字字面量的分隔符(1_000);并且使Array.prototype.sort更加精确,减少了导致实现定义的排序顺序的不确定情况。

ECMAScript 2022,第13版,引入了顶层await,允许在模块顶层使用关键字;新的类元素:公共和私有实例字段、公共和私有静态字段、私有实例方法和访问器、以及私有静态方法和访问器;类中的静态块,用于每类评估初始化;#x in obj语法,用于测试对象上私有字段的存在;通过/d标志的正则表达式匹配索引,提供匹配子字符串的起始和结束索引;Error对象上的cause属性,用于记录错误中的因果链;用于字符串、数组和类型化数组at方法,允许相对索引;以及Object.hasOwnObject.prototype.hasOwnProperty的便捷替代。

ECMAScript 2023,第14版,引入了Array.prototypeTypedArray.prototype上的toSortedtoReversedwithfindLastfindLastIndex方法,以及Array.prototype上的toSpliced方法;增加了对文件开头#!注释的支持,以更好地促进可执行ECMAScript文件;并允许在弱集合中使用大多数符号作为键。

ECMAScript 2024,第15版,增加了调整和转移ArrayBuffers和SharedArrayBuffers大小的功能;添加了用于创建具有更高级功能的字符串集的RegExp/v标志;引入了用于构建Promise的便捷方法Promise.withResolvers、用于数据聚合的Object.groupByMap.groupBy方法、用于异步等待共享内存更改的Atomics.waitAsync方法,以及用于检查和确保字符串仅包含格式良好的Unicode的String.prototype.isWellFormedString.prototype.toWellFormed方法。

代表许多组织的数十个人在Ecma TC39中对这一版本的开发以及之前的版本做出了非常重要的贡献。此外,还出现了一个支持TC39的ECMAScript工作的活跃社区。这个社区审查了无数草案,提交了数千个错误报告,进行了实现实验,贡献了测试套件,并向全球开发者社区介绍了ECMAScript。不幸的是,不可能识别和感谢每一个为这项工作做出贡献的人和组织。

Allen Wirfs-Brock
ECMA-262,第六版项目编辑

Brian Terlson
ECMA-262,第七版至第十版项目编辑

Jordan Harband
ECMA-262,第十版至第十二版项目编辑

Shu-yu Guo
ECMA-262,第十二版至第十五版项目编辑

Michael Ficarra
ECMA-262,第十二版至第十五版项目编辑

Kevin Gibbons
ECMA-262,第十二版至第十五版项目编辑

1 范围

本标准定义了ECMAScript 2024通用编程语言。

2 一致性

符合ECMAScript规范的实现必须提供并支持本规范中描述的所有类型、值、对象、属性、函数和程序语法及语义。

符合ECMAScript规范的实现必须按照最新版本的Unicode标准和ISO/IEC 10646解释源文本输入。

提供支持不同语言和国家的语言和文化习俗的应用编程接口(API)的符合ECMAScript规范的实现必须实现ECMA-402最新版本中与本规范兼容的接口。

符合ECMAScript规范的实现可以提供本规范中未描述的其他类型、值、对象、属性和函数。特别是,符合ECMAScript规范的实现可以为本规范中描述的对象提供本规范中未描述的属性和值。

符合ECMAScript规范的实现可以支持本规范中未描述的程序和正则表达式语法。特别是,符合ECMAScript规范的实现可以支持使用本规范第12.7.2节中提到的任何“未来保留字”的程序语法。

符合ECMAScript规范的实现不得实现本规范第17.1节中列出的任何禁用扩展。

符合ECMAScript规范的实现不得重新定义任何不是实现定义实现近似主机定义的设施。

符合ECMAScript规范的实现可以选择实现或不实现规范性可选的小节。如果实现了任何规范性可选行为,则必须实现包含的规范性可选条款中的所有行为。本规范中用彩色框中的“规范性可选”一词来表示规范性可选条款,如下所示。

2.1 示例规范性可选条款标题

示例条款内容。

符合ECMAScript规范的实现必须实现遗留小节,除非它们也被标记为规范性可选。遗留小节中指定的所有语言特性和行为都具有一个或多个不理想的特性。然而,它们在现有应用程序中的持续使用阻止了它们从本规范中删除。这些特性不被视为ECMAScript核心语言的一部分。程序员在编写新的ECMAScript代码时不应使用或假设这些特性和行为的存在。

2.2 示例遗留条款标题

示例条款内容。

2.3 示例遗留规范性可选条款标题

示例条款内容。

3 规范性引用

下列引用文件对于本文档的应用是必不可少的。对于有日期的引用,仅适用于所引用的版本。对于无日期的引用,适用于引用文件的最新版本(包括任何修正案)。

IEEE 754-2019IEEE 浮点算术标准

Unicode 标准。
https://unicode.org/versions/latest

ISO/IEC 10646,信息技术 — 通用多八位编码字符集 (UCS) 加上修正案1:2005、修正案2:2006、修正案3:2008、修正案4:2008和其他修正案和勘误,或其后续版本。

ECMA-402,ECMAScript 国际化 API 规范,特别是与本规范版本相对应的年度版。
https://www.ecma-international.org/publications-and-standards/standards/ecma-402/

ECMA-404,JSON 数据交换格式
https://www.ecma-international.org/publications-and-standards/standards/ecma-404/

4 概述

本节包含 ECMAScript 语言的非规范性概述。

ECMAScript 是一种面向对象的编程语言,用于在 宿主环境 中执行计算和操作计算对象。本规范中定义的 ECMAScript 并不打算是计算自给自足的;实际上,本规范没有规定外部数据的输入或计算结果的输出。相反,预计 ECMAScript 程序的计算环境不仅会提供本规范中描述的对象和其他设施,还会提供某些环境特定的对象,这些对象的描述和行为超出了本规范的范围,只是表明它们可能提供某些属性可以从 ECMAScript 程序中访问和调用的函数。

ECMAScript 最初设计为一种脚本语言,但现已广泛用作通用编程语言。脚本语言 是一种用于操作、定制和自动化现有系统功能的编程语言。在这些系统中,有用的功能已经通过用户界面可用,脚本语言是将这些功能暴露给程序控制的机制。这样,现有系统就提供了一个对象和设施的 宿主环境,从而完善了脚本语言的功能。脚本语言旨在供专业和非专业程序员使用。

ECMAScript 最初设计为一种 Web 脚本语言,提供一种机制来在浏览器中使网页生动起来,并作为基于 Web 的客户端-服务器架构的一部分执行服务器计算。ECMAScript 现在用于为各种 宿主环境 提供核心脚本功能。因此,本文件中规定的核心语言与任何特定的 宿主环境 无关。

ECMAScript 的使用已经超出了简单的脚本编写,它现在用于许多不同环境和规模的全方位编程任务。随着 ECMAScript 使用范围的扩大,它提供的功能和设施也在扩展。ECMAScript 现在是一种功能齐全的通用编程语言。

4.1 Web脚本

Web浏览器为客户端计算提供了一个ECMAScript 宿主环境,包括表示窗口、菜单、弹出窗口、对话框、文本区域、锚点、框架、历史记录、Cookies以及输入/输出的对象。此外,宿主环境还提供了一种将脚本代码附加到事件(如焦点更改、页面和图像加载、卸载、错误和中止、选择、表单提交和鼠标操作)的方法。脚本代码出现在HTML中,显示的页面是用户界面元素和固定和计算文本及图像的组合。脚本代码对用户交互有反应,因此不需要主程序。

Web服务器为服务器端计算提供了不同的宿主环境,包括表示请求、客户端和文件的对象;以及锁定和共享数据的机制。通过结合使用浏览器端和服务器端脚本,可以在客户端和服务器之间分配计算,同时为基于Web的应用程序提供定制的用户界面。

每个支持ECMAScript的Web浏览器和服务器都提供自己的宿主环境,从而完成ECMAScript的执行环境。

4.2 宿主和实现

为了帮助将ECMAScript集成到宿主环境中,本规范将某些功能的定义(例如,抽象操作)全部或部分地推迟到本规范之外的来源。在编辑上,本规范区分了以下几种推迟定义的方式。

实现是进一步定义附录D中列出的功能或那些标记为实现定义实现近似的功能的外部来源。在非正式使用中,实现是指具体的人工制品,例如特定的网络浏览器。

实现定义的功能是指将其定义推迟到外部来源而没有进一步的限定。本规范对特定行为没有做出任何建议,符合规范的实现可以在本规范提出的约束范围内选择任何行为。

实现近似的功能是指将其定义推迟到外部来源,同时建议一种理想行为。虽然符合规范的实现可以在本规范提出的约束范围内选择任何行为,但鼓励它们尽量接近理想。一些数学操作,例如Math.exp,属于实现近似

宿主是进一步定义附录D中列出的功能,但不进一步定义其他实现定义实现近似功能的外部来源。在非正式使用中,宿主是指以相同方式通过附录D与本规范接口的所有实现集,例如所有网络浏览器的集合。宿主通常是一个外部规范,例如WHATWG HTML (https://html.spec.whatwg.org/)。换句话说,宿主定义的功能通常在外部规范中进一步定义。

宿主挂钩 是一个由外部来源全部或部分定义的抽象操作。所有 宿主挂钩 必须列在附录 D 中。宿主挂钩 必须至少符合以下要求:

宿主定义 的功能是将其定义推迟到外部来源而没有进一步的限定,并列在附录 D 中。不是 宿主 的实现也可以提供 宿主定义 的功能定义。

宿主环境 是所有 宿主定义 功能的特定定义选择。宿主环境 通常包括允许获取输入和提供输出的对象或函数,作为 宿主定义 属性的一部分的 全局对象

本规范遵循始终使用最具体术语的编辑约定。例如,如果一个功能是 宿主定义 的,则不应称其为 实现定义

宿主和实现可以通过本规范中定义的语言类型、规范类型、抽象操作、语法生成、内在对象和内在符号与本规范接口。

4.3 ECMAScript 概述

以下是 ECMAScript 的非规范性概述,并未描述该语言的所有部分。该概述不属于标准的正式部分。

ECMAScript 是基于对象的:基本语言和宿主功能由对象提供,ECMAScript 程序是一个相互通信的对象集合。在 ECMAScript 中,对象 是具有零个或多个 属性 的集合,每个属性都有确定如何使用该属性的 特性 —— 例如,当属性的可写特性(Writable attribute)设置为 false 时,任何试图通过执行的 ECMAScript 代码分配不同值给该属性的操作都会失败。属性是包含其他对象、原始值函数 的容器。原始值是以下内置类型之一的成员:UndefinedNullBooleanNumberBigIntStringSymbol;对象是内置类型 Object 的成员;函数是可调用对象。通过属性与对象关联的函数称为 方法

ECMAScript 定义了一组 内置对象,完善了 ECMAScript 实体的定义。这些内置对象包括 全局对象;对语言的 运行时语义 基本的对象,包括 ObjectFunctionBooleanSymbol 及各种 Error 对象;表示和操作数值的对象,包括 MathNumberDate;处理文本的对象 StringRegExp;值的索引集合的对象,包括 Array 和九种不同类型的元素具有特定数值表示的 Typed Arrays;键控集合,包括 MapSet 对象;支持结构化数据的对象,包括 JSON 对象、ArrayBufferSharedArrayBufferDataView;支持控制抽象的对象,包括生成器函数和 Promise 对象;以及反射对象,包括 ProxyReflect

ECMAScript 还定义了一组内置 运算符。ECMAScript 运算符包括各种一元运算符、乘法运算符、加法运算符、位移运算符、关系运算符、相等运算符、二进制位运算符、二进制逻辑运算符、赋值运算符和逗号运算符。

大型 ECMAScript 程序由 模块 支持,允许程序划分为多个语句和声明的序列。每个模块明确标识其使用的需要由其他模块提供的声明,以及哪些声明可供其他模块使用。

ECMAScript 语法故意类似于 Java 语法。ECMAScript 语法被放宽,以使其作为一种易于使用的脚本语言。例如,变量不需要声明其类型,属性也没有关联类型,定义的函数也不需要在调用之前出现在文本上。

4.3.1 对象

尽管 ECMAScript 包含类定义的语法,但 ECMAScript 对象并非如 C++、Smalltalk 或 Java 中的类为基础。相反,对象可以通过多种方式创建,包括字面量表示法或 构造函数,这些构造函数创建对象,然后通过为其属性分配初始值来初始化全部或部分对象。每个 构造函数 都是一个具有名为 "prototype" 属性的函数,该属性用于实现 基于原型的继承共享属性。对象通过在 new 表达式中使用 构造函数 创建;例如,new Date(2009, 11) 创建一个新的 Date 对象。不使用 new 调用 构造函数 会产生不同的结果,这取决于 构造函数。例如,Date() 生成当前日期和时间的字符串表示,而不是对象。

每个由 构造函数 创建的对象都有一个隐式引用(称为对象的 原型),指向其 构造函数"prototype" 属性的值。此外,原型可能有一个非 null 的隐式引用指向其原型,依此类推;这称为 原型链。当引用对象中的属性时,该引用是指向原型链中第一个包含该名称属性的对象中的属性。换句话说,首先检查直接提到的对象是否包含该属性;如果该对象包含命名属性,则该引用指向的就是该属性;如果该对象不包含命名属性,则接下来检查该对象的原型;依此类推。

图 1:对象/原型关系
许多框和箭头的图片。

在基于类的面向对象语言中,通常状态由实例承载,方法由类承载,并且继承仅限于结构和行为。而在 ECMAScript 中,状态和方法由对象承载,而结构、行为和状态都是继承的。

所有不直接包含其原型所包含的特定属性的对象共享该属性及其值。图 1 说明了这一点:

CF 是一个 构造函数(也是一个对象)。通过使用 new 表达式创建了五个对象:cf1cf2cf3cf4cf5。这些对象每个都包含名为 "q1""q2" 的属性。虚线表示隐式原型关系;例如,cf3 的原型是 CFp构造函数 CF 本身有两个属性,分别为 "P1""P2",它们在 CFpcf1cf2cf3cf4cf5 中不可见。CFp 中名为 "CFP1" 的属性由 cf1cf2cf3cf4cf5 共享(但不包括 CF),以及 CFp 的隐式原型链中除 "q1""q2""CFP1" 之外的任何属性。注意,CFCFp 之间没有隐式原型链接。

与大多数基于类的对象语言不同,可以通过分配值动态地向对象添加属性。也就是说,构造函数 不需要命名或分配所有或任何构造对象的属性。在上图中,可以通过向 CFp 中的属性分配新值,为 cf1cf2cf3cf4cf5 添加一个新的共享属性。

尽管 ECMAScript 对象本质上不是基于类的,但根据 构造函数、原型对象和方法的共同模式定义类样抽象通常是方便的。ECMAScript 内置对象本身遵循这样的类样模式。从 ECMAScript 2015 开始,ECMAScript 语言包括语法类定义,允许程序员简洁地定义符合内置对象使用的相同类样抽象模式的对象。

4.3.2 ECMAScript 的严格变体

ECMAScript 语言认识到某些用户可能希望限制其使用语言中某些功能的可能性。他们可能出于安全考虑,避免他们认为容易出错的功能,获得增强的错误检查,或出于其他原因。为了支持这种可能性,ECMAScript 定义了语言的严格变体。语言的严格变体排除了一些常规 ECMAScript 语言的特定语法和语义特性,并修改了某些特性的详细语义。严格变体还指定了在非严格形式的语言未指定为错误的情况下必须通过抛出错误异常来报告的其他错误条件。

ECMAScript 的严格变体通常称为语言的严格模式。严格模式的选择和 ECMAScript 严格模式语法和语义的使用明确在单个 ECMAScript 源文本 单元级别进行,如 11.2.2 中所述。由于在语法源文本单元级别选择严格模式,因此严格模式仅对该源文本单元内具有局部效果的限制。严格模式不会限制或修改必须在多个源文本单元之间一致操作的 ECMAScript 语义。完整的 ECMAScript 程序可以由严格模式和非严格模式 ECMAScript 源文本 单元组成。在这种情况下,严格模式仅在实际执行在严格模式源文本单元中定义的代码时才适用。

为了符合本规范,ECMAScript 实现必须实现完整的无限制 ECMAScript 语言和本规范定义的 ECMAScript 语言的严格变体。此外,实现必须支持将无限制和严格模式源文本单元组合成一个单一的组合程序。

4.4 术语和定义

在本文件中,适用以下术语和定义。

4.4.1 实现近似 (implementation-approximated)

一个 实现近似 设施是由外部来源全部或部分定义的,但在本规范中有推荐的理想行为。

4.4.2 实现定义 (implementation-defined)

一个 实现定义 设施是由外部来源全部或部分定义的。

4.4.3 主机定义 (host-defined)

实现定义 相同。

注意

编辑说明,参见 4.2 条款。

4.4.4 类型 (type)

数据值集合,定义见 第 6 章

4.4.5 原始值 (primitive value)

是 Undefined、Null、Boolean、Number、BigInt、Symbol 或 String 类型中的一个成员,定义见 第 6 章

注意

原始值是在语言实现的最低层直接表示的数据。

4.4.6 对象 (object)

Object 类型的成员。

注意

对象是属性的集合,并且有一个单一的原型对象。原型可以是 null

4.4.7 构造函数 (constructor)

函数对象,用于创建和初始化对象。

注意

构造函数的 prototype 属性的值是一个原型对象,用于实现继承和共享属性。

4.4.8 原型 (prototype)

为其他对象提供共享属性的对象。

注意

当一个 构造函数 创建一个对象时,该对象隐式地引用了该构造函数的 prototype 属性,用于解析属性引用。构造函数的 prototype 属性可以通过程序表达式 constructor.prototype 引用,并且添加到对象原型中的属性通过继承在所有共享该原型的对象中共享。或者,可以使用 Object.create 内置函数创建具有显式指定原型的新对象。

4.4.9 普通对象 (ordinary object)

具有所有对象必须支持的基本内部方法默认行为的对象

4.4.10 特殊对象 (exotic object)

在一个或多个基本内部方法上不具有默认行为的对象

注意

任何不是 普通对象 的对象都是 特殊对象

4.4.11 标准对象 (standard object)

其语义由本规范定义的对象

4.4.12 内置对象 (built-in object)

由 ECMAScript 实现指定和提供的对象

注意

标准内置对象在本规范中定义。ECMAScript 实现可以指定和提供其他种类的内置对象。

4.4.13 未定义值 (undefined value)

当变量未被赋值时使用的原始值

4.4.14 Undefined 类型 (Undefined type)

唯一值为 undefined 的类型

4.4.15 空值 (null value)

表示故意缺少任何对象值的原始值

4.4.16 Null 类型 (Null type)

唯一值为 null 的类型

4.4.17 布尔值 (Boolean value)

属于 Boolean 类型 的成员

注意

只有两个布尔值,truefalse

4.4.18 Boolean 类型 (Boolean type)

由原始值 truefalse 组成的类型

4.4.19 Boolean 对象 (Boolean object)

属于 对象类型 的成员,是标准内置 Boolean 构造函数 的实例

注意

Boolean 对象是通过在 new 表达式中使用 Boolean 构造函数 并提供一个布尔值作为参数来创建的。生成的对象具有一个内部插槽,其值为布尔值。可以将 Boolean 对象强制转换为布尔值。

4.4.20 字符串值 (String value)

原始值,是一个 有限 的有序序列,包含零个或多个 16 位无符号 整数

注意

字符串值是 字符串类型 的成员。序列中的每个 整数 值通常代表 UTF-16 文本的单个 16 位单元。然而,ECMAScript 对这些值没有任何限制或要求,除了它们必须是 16 位无符号 整数

4.4.21 字符串类型 (String type)

所有可能的字符串值的集合

4.4.22 字符串对象 (String object)

属于 对象类型 的成员,是标准内置字符串 构造函数 的实例

注意

字符串对象是通过在 new 表达式中使用字符串 构造函数 并提供一个字符串值作为参数来创建的。生成的对象具有一个内部插槽,其值为字符串值。可以通过将字符串 构造函数 作为函数调用来将字符串对象强制转换为字符串值 (22.1.1.1)。

4.4.23 Number 值 (Number value)

对应双精度 64 位二进制格式 IEEE 754-2019 值的原始值

注意

Number 值是 Number 类型 的成员,是数字的直接表示。

4.4.24 Number 类型 (Number type)

所有可能的 Number 值的集合,包括特殊的“非数值” (NaN) 值、正无穷大和负无穷大

4.4.25 Number 对象 (Number object)

属于 对象类型 的成员,是标准内置 Number 构造函数 的实例

注意

Number 对象是通过在 new 表达式中使用 Number 构造函数 并提供一个 Number 值作为参数来创建的。生成的对象具有一个内部插槽,其值为 Number 值。可以通过将 Number 构造函数 作为函数调用来将 Number 对象强制转换为 Number 值 (21.1.1.1)。

4.4.26 无穷大 (Infinity)

表示正无穷大的 Number 值

4.4.27 NaN

表示 IEEE 754-2019 “非数值” 的 Number 值

4.4.28 BigInt 值 (BigInt value)

对应任意精度 整数 值的原始值

4.4.29 BigInt 类型 (BigInt type)

所有可能的 BigInt 值的集合

4.4.30 BigInt 对象 (BigInt object)

属于 对象类型 的成员,是标准内置 BigInt 构造函数 的实例

4.4.31 Symbol 值 (Symbol value)

表示唯一的、非字符串对象 属性键 的原始值

4.4.32 Symbol 类型 (Symbol type)

所有可能的 Symbol 值的集合

4.4.33 Symbol 对象 (Symbol object)

属于 对象类型 的成员,是标准内置 Symbol 构造函数 的实例

4.4.34 函数 (function)

属于 对象类型 的成员,可以作为子例程调用

注意

除了它的属性之外,函数还包含可执行代码和状态,这些代码和状态决定了它在调用时的行为。函数的代码可以是 ECMAScript 编写的,也可以不是。

4.4.35 内置函数 (built-in function)

内置对象,是一个函数

注意

内置函数的例子包括 parseIntMath.exp宿主 或实现可能提供本规范中未描述的其他内置函数。

4.4.36 内置构造函数 (built-in constructor)

内置函数,是一个 构造函数

注意

内置 构造函数 的例子包括 ObjectFunction宿主 或实现可能提供本规范中未描述的其他内置 构造函数

4.4.37 属性 (property)

对象的一部分,关联一个键(字符串值或 Symbol 值)和一个值

注意

根据属性的形式,值可以直接表示为数据值(原始值、对象或 函数对象)或通过一对访问器函数间接表示。

4.4.38 方法 (method)

作为属性值的函数

注意

当函数作为对象的方法调用时,对象会作为其 this 值传递给函数。

4.4.39 内置方法 (built-in method)

作为内置函数的方法

注意

标准内置方法在本规范中定义。宿主 或实现可能提供本规范中未描述的其他内置方法。

4.4.40 属性 (attribute)

定义属性某些特性的内部值

4.4.41 自有属性 (own property)

直接包含在对象中的属性

4.4.42 继承属性 (inherited property)

对象的属性,不是自有属性,但它是对象原型的属性(自有属性或继承属性)

4.5 本规范的组织结构 (Organization of This Specification)

本规范的其余部分组织如下:

5 节定义了整个规范中使用的符号约定。

6 节到第 10 节定义了 ECMAScript 程序运行的执行环境。

11 节到第 17 节定义了实际的 ECMAScript 编程语言,包括其语法编码和所有语言特性的执行语义。

18 节到第 28 节定义了 ECMAScript 标准库。它们包括所有可供 ECMAScript 程序在执行时使用的标准对象的定义。

29 节描述了对 SharedArrayBuffer 支持的内存的访问和 Atomics 对象的方法的内存一致性模型。

5 符号约定

5.1 句法和词法语法

5.1.1 上下文无关文法

一个上下文无关文法由若干生成式组成。每个生成式的左侧都有一个抽象符号,称为非终结符,右侧则是一系列零个或多个非终结符和终结符符号。对于每个文法,终结符号来自指定的字母表。

链生成式是右侧有且只有一个非终结符号以及零个或多个终结符号的生成式。

从一个由单个特殊非终结符组成的句子开始,称为目标符号,给定的上下文无关文法指定了一种语言,即通过不断将序列中的任何非终结符替换为其左侧为该非终结符的生成式的右侧所能产生的终结符号的(可能是无限的)集合。

5.1.2 词法和正则表达式文法

ECMAScript 的词法文法12 章中给出。该文法的终结符是符合 SourceCharacter 规则的 Unicode 代码点,这些规则定义在 11.1 章中。它定义了一组生成式,从 目标符号 InputElementDivInputElementTemplateTailInputElementRegExpInputElementRegExpOrTemplateTailInputElementHashbangOrRegExp 开始,描述了如何将这些代码点的序列转换为输入元素的序列。

除空白和注释外的输入元素构成 ECMAScript 语法文法的终结符,称为 ECMAScript 标记。这些标记是 ECMAScript 语言的 保留字、标识符、字面量和标点符号。此外,行终止符虽然不被视为标记,但也成为输入元素流的一部分,并指导自动分号插入过程(12.10)。简单的空白和单行注释被丢弃,不会出现在语法文法的输入元素流中。如果一个 MultiLineComment(即形式为 /**/ 的注释,不论是否跨越多行)不包含行终止符,则它同样会被丢弃;但如果 MultiLineComment 包含一个或多个行终止符,则它将被一个单一的行终止符替代,成为语法文法输入元素流的一部分。

ECMAScript 的正则表达式文法22.2.1 章中给出。该文法的终结符也是由 SourceCharacter 定义的代码点。它定义了一组生成式,从 目标符号 Pattern 开始,描述了如何将代码点的序列转换为正则表达式模式。

词法和正则表达式文法的生成式通过两个冒号 “::” 作为分隔标点来区分。这两种文法共享一些生成式。

5.1.3 数值字符串文法

7.1.4.1 章节中出现了数值字符串文法。它的终结符是 SourceCharacter,用于从 目标符号 StringNumericLiteral 开始,将字符串翻译成数值(这与 数字字面量的词法文法 类似但不同)。

数值字符串文法的生成式通过三个冒号 “:::” 作为标点符号来区分,且从不用于解析源文本。

5.1.4 句法文法

ECMAScript 的 句法文法第13节第16节 中给出。该文法的终结符是由词法文法定义的 ECMAScript 标记(5.1.2)。它定义了一组生成式,从两个可选的 目标符号 ScriptModule 开始,描述了标记序列如何形成 ECMAScript 程序的句法上正确的独立组件。

当要将代码点流解析为 ECMAScript ScriptModule 时,首先通过重复应用词法文法将其转换为输入元素流;然后通过一次应用句法文法来解析该输入元素流。如果输入元素流中的标记不能解析为目标非终结符(ScriptModule)的单个实例,并且没有剩余标记,则输入流在句法上是错误的。

解析成功时,会构造一个 解析树,这是一个以根为起点的树结构,其中每个节点是一个 解析节点。每个解析节点都是文法中某个符号的实例;它表示可以从该符号派生的源文本范围。表示整个源文本的解析树的根节点是解析的 目标符号 的一个实例。当解析节点是非终结符的实例时,它也是以该非终结符作为左侧的某个生成式的实例。此外,它具有零个或多个子节点,每个符号一个:每个子节点都是相应符号的解析节点实例。

解析器的每次调用都会实例化新的解析节点,并且在解析相同源文本时永不重用。解析节点被认为是相同的解析节点,当且仅当它们表示相同的源文本范围,是相同文法符号的实例,并且是由同一次解析器调用生成的。

注释 1

多次解析相同的字符串会导致不同的解析节点。例如,考虑:

let str = "1 + 1;";
              eval(str);
              eval(str);

每次调用 eval 都会将 str 的值转换为 ECMAScript 源文本 并执行一个独立的解析,创建自己独立的解析节点树。这些树是不同的,即使每次解析操作的源文本都来自相同的字符串值。

注释 2
解析节点是规范产物,实现并不要求使用类似的数据结构。

句法文法的生成式通过使用一个冒号 “:” 作为标点符号来区分。

第13节第16节 中所述的句法文法并不完全说明哪些标记序列被接受为正确的 ECMAScript ScriptModule。某些附加的标记序列也被接受,即那些如果只在某些地方添加分号(如在行终止符之前)就能描述的序列。此外,如果行终止符出现在某些“尴尬”的地方,则由文法描述的某些标记序列也不被认为是可接受的。

在某些情况下,为避免歧义,句法文法使用了泛化生成式,允许不形成有效 ECMAScript ScriptModule 的标记序列。例如,这种技术用于对象字面量和对象解构模式。在这种情况下,提供了更严格的补充文法,进一步限制了可接受的标记序列。通常,早期错误 规则会声明,在某些上下文中,“P 必须覆盖 N”,其中 P 是解析节点(泛化生成式的实例),N 是补充文法中的非终结符。这意味着:

  1. 使用 N 作为目标符号重新解析最初由 P 匹配的标记序列。如果 N 采用文法参数,则它们设置为与最初解析 P 时相同的值。
  2. 如果标记序列可以解析为 N 的单个实例,并且没有剩余标记,则:
    1. 我们将该 N 的实例(解析节点,在给定 P 的情况下是唯一的)称为“由 P 覆盖的 N”。
    2. N 及其派生生成式的所有早期错误规则也适用于由 P 覆盖的 N
  3. 否则(如果解析失败),则为早期语法错误。

5.1.5 语法标记

5.1.5.1 终结符号

在ECMAScript语法中,一些终结符号显示为固定宽度字体。这些符号应当按照书写的样子准确出现在源文本中。以这种方式指定的所有终结符号码点都应被理解为来自基本拉丁块的适当Unicode码点,而不是来自其他Unicode范围的类似看起来的码点。终结符号中的一个码点不能通过\ UnicodeEscapeSequence来表达。

在其终结符号是单个Unicode码点的语法中(即,词汇、RegExp和数值字符串语法),连续的多个固定宽度码点出现在一个生产中,是一种简单的速记,用于表示相同的码点序列,写作独立的终结符号。

例如,产生式:

HexIntegerLiteral :: 0x HexDigits

是以下的简写形式:

HexIntegerLiteral :: 0 x HexDigits

相比之下,在句法语法中,连续的固定宽度码点构成一个单独的终结符号。

终结符号还有其他两种形式:

5.1.5.2 非终结符号与生产规则

非终结符号显示为斜体类型。非终结(也称为“产生式”)的定义是由被定义的非终结名称开始,后面跟着一个或多个冒号(冒号的数量表示生产所属的语法)。然后,非终结的一个或多个备选右侧在后续行中跟随。例如,句法定义:

WhileStatement : while ( Expression ) Statement

说明非终结WhileStatement 表示关键字while,后跟一个左括号,然后是一个Expression, 后跟一个右括号,然后是一个Statement。这里出现的ExpressionStatement本身也是非终结。作为另一个例子,句法定义:

ArgumentList : AssignmentExpression ArgumentList , AssignmentExpression

说明一个ArgumentList 可能代表一个单独的AssignmentExpression或一个ArgumentList, 后跟一个逗号,然后是一个AssignmentExpression。 这个ArgumentList的定义是递归的,即它是以自身为基础定义的。结果是,一个ArgumentList可能包含任意正数个参数,这些参数由逗号分隔,每个参数表达式都是一个AssignmentExpression。这种非终结的递归定义是常见的。

5.1.5.3 可选符号

下标后缀“opt”,可出现在终结符或非终结符之后,表示一个可选符号。包含可选符号的替代项实际上指定了两个右侧,一个省略可选元素,一个包含它。这意味着:

VariableDeclaration : BindingIdentifier Initializeropt

是一个方便的缩写:

VariableDeclaration : BindingIdentifier BindingIdentifier Initializer

和:

ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement

是一个方便的缩写:

ForStatement : for ( LexicalDeclaration ; Expressionopt ) Statement for ( LexicalDeclaration Expression ; Expressionopt ) Statement

反过来又是一个缩写:

ForStatement : for ( LexicalDeclaration ; ) Statement for ( LexicalDeclaration ; Expression ) Statement for ( LexicalDeclaration Expression ; ) Statement for ( LexicalDeclaration Expression ; Expression ) Statement

因此,在这个例子中,非终结符ForStatement 实际上有四个备选右侧。

5.1.5.4 语法参数

一个产生式可能会被形式为“[parameters]”的下标注释参数化,它可能作为由产生式定义的非终结符号的后缀出现。“parameters”可以是单个名称或逗号分隔的名称列表。参数化的产生式是一组产生式的简写,这些产生式定义了所有参数名称的组合,这些名称由下划线前缀,并附加到参数化的非终结符号上。这意味着:

StatementList[Return] : ReturnStatement ExpressionStatement

是以下的缩写:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement

并且:

StatementList[Return, In] : ReturnStatement ExpressionStatement

是以下的缩写:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement StatementList_In : ReturnStatement ExpressionStatement StatementList_Return_In : ReturnStatement ExpressionStatement

多个参数会产生组合数量的产生式,但并不是所有的产生式都必须在完整的语法中被引用。

产生式右侧的非终结符号的引用也可以被参数化。例如:

StatementList : ReturnStatement ExpressionStatement[+In]

等同于说:

StatementList : ReturnStatement ExpressionStatement_In

以及:

StatementList : ReturnStatement ExpressionStatement[~In]

相当于:

StatementList : ReturnStatement ExpressionStatement

一个非终结符的引用可能同时具有参数列表和“opt”后缀。例如:

VariableDeclaration : BindingIdentifier Initializer[+In]opt

是以下的缩写:

VariableDeclaration : BindingIdentifier BindingIdentifier Initializer_In

在右侧非终结符引用中,用“?”前缀参数名称,使得该参数值依赖于当前产生式左侧符号引用中参数名称的出现。例如:

VariableDeclaration[In] : BindingIdentifier Initializer[?In]

是以下的缩写:

VariableDeclaration : BindingIdentifier Initializer VariableDeclaration_In : BindingIdentifier Initializer_In

如果右侧的备选方案以“[+parameter]”为前缀,那么这个备选方案只在引用产生式的非终结符号时使用了指定的参数才可用。如果右侧的备选方案以“[~parameter]”为前缀,那么这个备选方案只在引用产生式的非终结符号时使用指定的参数才可用。这意味着:

StatementList[Return] : [+Return] ReturnStatement ExpressionStatement

是以下的缩写:

StatementList : ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement

并且:

StatementList[Return] : [~Return] ReturnStatement ExpressionStatement

是以下的缩写:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ExpressionStatement

5.1.5.5 one of

当语法定义中的冒号后面跟着“one of”这几个词时,它们表示接下来的每一行上的终结符号都是一个替代定义。例如,ECMAScript的词法语法包含以下产生式:

NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9

这只是一个方便的缩写,完整形式为:

NonZeroDigit :: 1 2 3 4 5 6 7 8 9

5.1.5.6 [empty]

如果产生式的右侧出现“[empty]”这一短语,它表示该产生式的右侧不包含任何终结符号或非终结符号。

5.1.5.7 前瞻限制

如果短语“[lookahead = seq]”出现在产生式的右侧,它表示只有当令牌序列seq是紧随其后的输入令牌序列的前缀时,才能使用该产生式。类似地,“[lookahead ∈ set]”,其中set是一个非空的有限令牌序列集合,表示只有当set中的某个元素是紧随其后的令牌序列的前缀时,才能使用该产生式。为了方便起见,该集合也可以写作非终结符,这种情况下它代表所有非终结符可以扩展到的令牌序列的集合。如果非终结符可以扩展到无限多个不同的令牌序列,则被认为是编辑错误。

这些条件可以被否定。“[lookahead ≠ seq]”表示只有当seq不是紧随其后的输入令牌序列的前缀时,才能使用包含的产生式,“[lookahead ∉ set]”表示只有当set中的没有元素是紧随其后的令牌序列的前缀时,才能使用该产生式。

例如,给定以下定义:

DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9 DecimalDigits :: DecimalDigit DecimalDigits DecimalDigit

定义如下:

LookaheadExample :: n [lookahead ∉ { 1, 3, 5, 7, 9 }] DecimalDigits DecimalDigit [lookahead ∉ DecimalDigit]

匹配字母n,后跟一个或多个十进制数字,第一个数字为偶数,或一个十进制数字,后面没有跟随另一个十进制数字。

注意,当这些短语在句法语法中使用时,可能无法明确识别紧随其后的令牌序列,因为确定后续的令牌需要知道在后续位置使用哪个词法目标符号。因此,当这些短语在句法语法中使用时,如果词法目标符号的选择可能会改变seq是否会成为生成的令牌序列的前缀,那么在前视限制中出现令牌序列seq(包括作为序列集合的一部分)被认为是编辑错误。

5.1.5.8 [no LineTerminator here]

如果在句法文法的生成式右侧出现短语“[no LineTerminator here]”,则表示该生成式是受限生成式:如果在指示位置的输入流中出现 LineTerminator,则不允许使用该生成式。例如,生成式:

ThrowStatement : throw [no LineTerminator here] Expression ;

表示如果在脚本中 throw 标记和 Expression 之间出现 LineTerminator,则不允许使用该生成式。

除非受限生成式禁止出现 LineTerminator,否则在输入元素流中的任何两个连续标记之间出现任何数量的 LineTerminator 都不会影响脚本的句法可接受性。

5.1.5.9 but not

生成式的右侧可以使用短语“but not”并指示要排除的扩展来指定不允许某些扩展。例如,生成式:

Identifier :: IdentifierName but not ReservedWord

意味着非终结符 Identifier 可以被替换为任何可以替换 IdentifierName 的代码点序列,前提是相同的代码点序列不能替换 ReservedWord

5.1.5.10 描述性短语

最后,在一些列出所有替代方案不切实际的情况下,使用无衬线字体的描述性短语来描述少数非终结符号:

SourceCharacter :: 任意 Unicode 代码点
<

5.2 算法约定

该规范经常使用编号列表来指定算法中的步骤。这些算法用于精确指定 ECMAScript 语言结构的所需语义。这些算法并不意味着必须使用任何特定的实现技术。实际上,可能有更有效的算法可用于实现给定的功能。

算法可以明确地用一个有序的、逗号分隔的别名序列参数化,这些别名在算法步骤中可用于引用在该位置传入的参数。可选参数用方括号([ , name ])表示,与算法步骤中的必需参数没有区别。参数列表的末尾可以出现一个剩余参数,以省略号(, ...name)表示。剩余参数捕获所有在必需参数和可选参数之后提供的参数,这些参数被编入一个 列表。如果没有这样的额外参数,那么这个 列表 将为空。

算法步骤可以细分为顺序子步骤。子步骤是缩进的,并且本身可以进一步分为缩进的子步骤。用大纲编号约定来标识子步骤,第一层子步骤用小写字母标记,第二层子步骤用小写罗马数字标记。如果需要超过三个层级,这些规则将重复,第四层使用数字标签。例如:

  1. 顶层步骤
    1. 子步骤。
    2. 子步骤。
      1. 子子步骤。
        1. 子子子步骤
          1. 子子子子步骤
            1. 子子子子子步骤

步骤或子步骤可以作为一个“if”谓词编写,条件化其子步骤。在这种情况下,只有当谓词为真时,子步骤才会被应用。如果步骤或子步骤以“else”一词开头,它是一个谓词,是与同一层级前一个“if”谓词步骤的否定。

步骤可以指定其子步骤的迭代应用。

以“Assert(断言):”开头的步骤断言其算法的不变条件。这种断言用来明确那些否则会是隐含的算法不变性。这样的断言不增加额外的语义要求,因此实现无需检查。它们仅用于澄清算法。

算法步骤可以使用“Let x be someValue”的形式声明任何值的命名别名。这些别名类似于引用,xsomeValue都指向相同的底层数据,对任何一个的修改都对双方可见。如果算法步骤想要避免这种类似引用的行为,应该明确地复制右侧值:“Let x be a copy of someValue”创建了someValue的一个浅拷贝。

一旦声明,别名可以在任何后续步骤中被引用,并且不能从别名声明之前的步骤中被引用。别名可以使用“Set x to someOtherValue”的形式进行修改。

5.2.1 抽象操作

为了便于在本规范的多个部分中使用,一些算法被称为抽象操作,它们被命名并以参数化的函数形式编写,以便可以从其他算法中通过名称引用它们。抽象操作通常使用函数应用风格引用,如 OperationName(arg1, arg2)。一些抽象操作被视为类似类的规范抽象中多态分派的方法。这种类似方法的抽象操作通常使用方法应用风格引用,例如 someValue.OperationName(arg1, arg2)。

5.2.2 语法指导操作

一个语法指导操作是一个命名操作,其定义包括多个算法,每个算法都与ECMAScript语法之一的一个或多个产生式相关联。具有多个替代定义的产生式通常会为每个替代定义有一个独特的算法。当一个算法与一个语法产生式相关联时,它可以引用产生式替代的终结符和非终结符,就好像它们是算法的参数一样。在这种方式下使用时,非终结符引用在解析源文本时匹配的实际替代定义。由语法产生式匹配的源文本或由其衍生的解析节点是从参与匹配的第一个终结符开始到参与匹配的最后一个终结符结束的源文本部分。

当一个算法与一个产生式替代相关联时,该替代通常显示时不包括任何“[ ]”语法注释。这样的注释只应影响替代的语法识别,对替代的相关语义没有影响。

语法指导操作通过使用下列算法中的步骤134的约定,通过解析节点和可选的其他参数调用。

  1. status为SyntaxDirectedOperation of SomeNonTerminal
  2. someParseNode为一些源文本的解析。
  3. 执行someParseNode的SyntaxDirectedOperation。
  4. 带参数"value"执行someParseNode的SyntaxDirectedOperation。

除非另有明确规定,所有链产生式都隐含为其左侧非终结符的每个操作提供定义。隐含的定义简单地重新应用同一个操作和相同的参数(如果有的话)到链产生式的唯一右侧非终结符,然后返回结果。例如,假设某个算法有一个步骤形式:“返回评估 of ”,并且存在一个产生式:

: { 语句列表 }

但是评估操作并未将算法与该产生式关联。在这种情况下,评估操作隐含地包括如下形式的关联:

运行时语义:评估

: { 语句列表 }
  1. 返回评估 of 语句列表

5.2.3 运行时语义

需要在运行时调用以指定语义的算法称为运行时语义。运行时语义由抽象操作语法指导操作定义。

5.2.3.1 完成(completionRecord

抽象操作完成接受参数completionRecord(一个完成记录),并返回一个完成记录。此操作用于强调正在返回一个完成记录。在被调用时,它执行以下步骤:

  1. 断言completionRecord 是一个完成记录
  2. 返回completionRecord

5.2.3.2 抛出异常

算法步骤中提到抛出异常的,如:

  1. 抛出一个TypeError异常。

意味着与以下内容相同:

  1. 返回ThrowCompletion(新创建的TypeError对象)。

5.2.3.3 ReturnIfAbrupt

算法步骤中提到或等同于以下内容:

  1. ReturnIfAbrupt(argument)。

意味着:

  1. Assertargument 是一个Completion Record
  2. 如果 argument 是一个abrupt completion,返回Completion(argument)。
  3. 否则,将 argument 设置为 argument.[[Value]]

算法步骤中提到或等同于:

  1. ReturnIfAbrupt(AbstractOperation())。

意味着:

  1. hygienicTemp 是 AbstractOperation()。
  2. AsserthygienicTemp 是一个Completion Record
  3. 如果 hygienicTemp 是一个abrupt completion,返回Completion(hygienicTemp)。
  4. 否则,将 hygienicTemp 设置为 hygienicTemp.[[Value]]

hygienicTemp 是短暂的,仅在涉及 ReturnIfAbrupt 的步骤中可见。

算法步骤中提到或等同于:

  1. result 是 AbstractOperation(ReturnIfAbrupt(argument))。

意味着:

  1. Assertargument 是一个Completion Record
  2. 如果 argument 是一个abrupt completion,返回Completion(argument)。
  3. 否则,将 argument 设置为 argument.[[Value]]
  4. result 是 AbstractOperation(argument)。

5.2.3.4 ReturnIfAbrupt 简写

抽象操作语法指导操作调用时,前缀为?表示应当应用ReturnIfAbrupt到产生的完成记录。例如,步骤:

  1. ? OperationName().

等同于以下步骤:

  1. ReturnIfAbrupt(OperationName())。

同样,对于方法应用风格,步骤:

  1. someValue.OperationName().

等同于:

  1. ReturnIfAbrupt(someValue.OperationName())。

同样地,前缀!用来表示以下对抽象或语法指导操作的调用绝不会返回一个突然完成,并且结果中的完成记录[[Value]]字段应当代替操作的返回值使用。例如,步骤:

  1. val 是 ! OperationName().

等同于以下步骤:

  1. val 是 OperationName()。
  2. Assertval 是一个正常完成
  3. val 设置为 val.[[Value]]

语法指导操作运行时语义中使用这种简写,通过在操作调用前放置!?

  1. 执行 ! SyntaxDirectedOperation of NonTerminal

5.2.3.5 隐式正常完成

在声明返回完成记录抽象操作和所有内置函数中,返回的值首先传递给NormalCompletion,并使用其结果。此规则不适用于Completion算法内部,或当返回的值在该步骤中明确标记为完成记录的情况;这些情况包括:

如果通过任何其他方式从这样的抽象操作中返回完成记录,将是一个编辑错误。例如,在这些抽象操作中,

  1. 返回true

意味着与任何一种

  1. 返回NormalCompletion(true)。

  1. completionNormalCompletion(true)。
  2. 返回Completion(completion)。

  1. 返回完成记录 { [[Type]]: normal, [[Value]]: true, [[Target]]: empty }。

注意,通过ReturnIfAbrupt扩展,允许以下示例,因为在扩展的步骤中,应用Completion的结果在突然情况下直接返回,并且在正常情况下解包后隐式应用NormalCompletion

  1. 返回 ? completion

以下示例将是一个编辑错误,因为在该步骤中没有注明正在返回完成记录

  1. completionNormalCompletion(true)。
  2. 返回completion

5.2.4 静态语义

无上下文语法并不足以表达所有定义流式输入元素是否形成可评估的 ECMAScript ScriptModule 的规则。在某些情况下,需要使用 ECMAScript 算法约定或描述性要求来表达额外的规则。这些规则始终与语法的产生式相关联,并称为产生式的静态语义

静态语义规则具有名称,并通常使用算法定义。命名的静态语义规则与语法产生式相关联,具有多个备选定义的产生式通常对每个适用的命名静态语义规则有一个单独的算法。

静态语义规则的一种特殊类型是早期错误规则早期错误规则定义了特定语法产生式相关的早期错误条件(参见章节17)。大多数早期错误规则的评估在本规范的算法中未显式调用。符合要求的实现必须在首次评估ScriptModule之前,验证用于解析该ScriptModule的所有早期错误规则。如果违反了任何早期错误规则,则ScriptModule无效,无法评估。

5.2.5 数学运算

本规范参考以下数值类型:

  • 数学值:任意实数,作为默认的数值类型使用。
  • 扩展数学值数学值 加上 +∞ 和 -∞。
  • 数字:IEEE 754-2019 双精度浮点数值。参见 IEEE 754-2019
  • BigIntsECMAScript 语言值,表示与整数 整数 一一对应的任意整数。

在本规范的术语中,数值使用下标后缀来区分不同的数值类型。下标 𝔽 表示数字(Numbers),下标 表示大整数(BigInts)。没有下标后缀的数值指代 数学值

数值运算符(如 +、×、= 和 ≥)根据操作数的类型确定其操作。当应用于 数学值 时,这些运算符指代通常的数学运算。当应用于 扩展数学值 时,这些运算符指代扩展实数上的通常数学运算;未定义的不定形式在本规范中不予定义,其使用应视为编辑错误。当应用于数字(Numbers)时,这些运算符指代 IEEE 754-2019 中的相关运算。当应用于大整数(BigInts)时,这些运算符指代大整数的 数学值

一般来说,当本规范提到数值时,例如“y 的长度”或“由四位十六进制数字表示的 整数”,未明确指定数值类型时,默认指代 数学值。明确指代数字(Number)或大整数(BigInt)数值的短语将以明确标注方式出现;例如,“数字的数值,用于代码点数量…”或“大整数的数值…。”

不定义混合类型操作数(例如数字和 数学值)的数值运算符,其应视为本规范中的编辑错误。

本规范中大多数数值以十进制表示;同时也使用形如 0x 后跟数字 0-9 或 A-F 的十六进制值。

当本规范中使用术语 整数 时,指的是在 数学值 集合中的 整数,除非另有说明。当本规范中使用术语 整数数字 时,指的是数值其 数学值整数 集合中。

本文档中对 数学值、数字或大整数之间的转换总是明确的。从 数学值扩展数学值 x 到数字的转换表示为“数字的数值 x”或 𝔽(x),并在 6.1.6.1 中定义。从整数或大整数 x 到大整数的转换表示为“大整数的数值 x”或 ℤ(x)。从数字或大整数 x数学值 的转换表示为“数学值的数值 x”,或 ℝ(x)。对于 数学值的数值 +0𝔽-0𝔽,其为 数学值 0。对于非 有限 值,其 数学值的数值 未定义。对于 x扩展数学值的数值,其为 数学值的数值,对于 有限 值为 +∞ 和 -∞,对于 +∞𝔽-∞𝔽 分别为 +∞ 和 -∞,对于 NaN 未定义。

数学函数 abs(x) 计算 x 的绝对值,如果 x < 0,则结果为 -x,否则结果为 x 本身。

数学函数 min(x1, x2, ..., xN) 计算 x1xN 中的最小值。数学函数 max(x1, x2, ..., xN) 计算 x1xN 中的最大值。这些数学函数的定义域和值域为 扩展数学值

记法 “x modulo y”(y 必须为 有限 且非零)计算一个与 y 同号(或零)的值 k,使得 abs(k) < abs(y) 且 x - k = q × y,其中 q 是某个 整数

短语 "将 x 夹在 lowerupper 之间"(其中 x扩展数学值,而 lowerupper数学值,满足 lowerupper)的结果是:如果 x < lower,则产生 lower;如果 x > upper,则产生 upper;否则产生 x

数学函数 floor(x) 计算不大于 x 的最大 整数(接近 +∞)。

注意

floor(x) = x - (x modulo 1).

数学函数 truncate(x) 通过朝零方向舍入移除 x 的小数部分,如果 x < 0,则产生 -floor(-x),否则产生 floor(x)

数学函数 min, max, abs, floor, 和 truncate 对于 Numbers 和 BigInts 都没有定义,任何使用具有非 数学值 参数的方法在本规范中应视为编辑错误。

从下界 a 到上界 b区间 是可能是无限的、可能为空的、相同数值类型的数值集合。每个边界都将描述为包含或排除,但不会同时包含。有四种类型的区间,如下所示:

例如,从 1(包含)到 2(排除)的 区间 包含所有介于 1 和 2 之间的 数学值,包括 1 但不包括 2。在定义区间的目的上,-0𝔽 < +0𝔽,因此,例如,下界为 +0𝔽包含区间 包括 +0𝔽 但不包括 -0𝔽NaN 永远不包括在一个 区间 中。

5.2.6 值表示法

在本规范中,ECMAScript 语言值粗体 显示。例如 nulltrue"hello"。这些与 ECMAScript 源文本Function.prototype.applylet n = 42; 区分开来。

5.2.7 身份

在本规范中,规范值和 ECMAScript 语言值 都被比较是否相等。在比较相等性时,值可以分为两类。如果所有的固有特性(如 整数 的大小或序列的长度)都相同,则没有身份标识的值与其他没有身份标识的值相等。没有身份标识的值可以在未先前引用的情况下通过完全描述其特性来显示。相反,每个带有身份标识的值都是唯一的,因此只与自身相等。带有身份标识的值类似于没有身份标识的值,但具有一个额外的不可预测、不可更改、全局唯一的特征,称为身份。对现有带有身份标识的值的引用不能仅通过描述来显示,因为身份本身是无法描述的;相反,必须明确地将对这些值的引用从一个地方传递到另一个地方。一些带有身份标识的值是可变的,因此可以在原地更改其特性(除了其身份),从而使所有持有该值的人都能观察到新的特性。没有身份标识的值永远不等于带有身份标识的值。

从本规范的角度来看,“is”一词用于比较两个值是否相等,例如“如果booltrue,则...”,而“contains”一词用于使用相等性比较在列表中搜索值,例如“如果list包含一个Recordr,使得r.[[Foo]]true,则...”。值的规范身份决定了这些比较的结果,并在本规范中是公理性的。

从 ECMAScript 语言的角度来看,语言值使用SameValue抽象操作及其传递调用的抽象操作进行相等性比较。这些比较的算法操作决定了ECMAScript 语言值语言身份

对于规范值,没有规范身份的值包括但不限于:数学值扩展数学值ECMAScript 源文本代理对指令前言等;UTF-16 代码单元;Unicode 代码点;枚举抽象操作,包括语法导向操作主机钩子等;有序对。 具有规范身份的规范值包括但不限于:记录的任何种类,包括属性描述符私有元素等;解析节点列表集合关系抽象闭包数据块私有名称执行上下文执行上下文堆栈代理标识符;以及等待列表记录

规范身份对于所有ECMAScript 语言值都与语言身份一致,除了由Symbol.for生成的Symbol值。没有规范身份和语言身份的ECMAScript语言值包括:undefinednull布尔值字符串数字,和大整数。具有规范身份和语言身份的ECMAScript语言值包括:Symbol,但不包括由Symbol.for生成的Symbol值,以及对象

6 ECMAScript 数据类型和值

本规范中的算法操作值,每个值都有一个关联的类型。可能的值类型正是本条款中定义的那些类型。类型进一步分为ECMAScript 语言类型和规范类型。

在本规范中,“Type(x)”表示“x类型”,其中“类型”指的是本条款中定义的ECMAScript语言和规范类型。

6.1 ECMAScript 语言类型

ECMAScript 语言类型对应于由 ECMAScript 程序员直接使用 ECMAScript 语言操作的值。ECMAScript 语言类型包括 Undefined、Null、Boolean、String、Symbol、Number、BigInt 和 Object。一个ECMAScript 语言值是由 ECMAScript 语言类型特征化的值。

6.1.1 Undefined 类型

Undefined 类型恰好有一个值,称为 undefined。任何未被赋值的变量具有值 undefined

6.1.2 Null 类型

Null 类型恰好有一个值,称为 null

6.1.3 Boolean 类型

Boolean 类型表示具有两个值的逻辑实体,称为 truefalse

6.1.4 String 类型

String 类型是所有有序序列的集合,这些序列由零个或多个 16 位无符号整数值(“元素”)组成,最多可以有 253 - 1 个元素。String 类型通常用于表示运行中的 ECMAScript 程序中的文本数据,其中 String 中的每个元素都被视为一个 UTF-16 代码单元值。每个元素被视为占据序列中的一个位置。这些位置使用非负整数进行索引。第一个元素(如果有)位于索引 0,下一个元素(如果有)位于索引 1,依此类推。String 的长度是其中的元素数(即 16 位值)。空字符串的长度为零,因此不包含任何元素。

不解释 String 内容的 ECMAScript 操作不应用进一步的语义。对解释 String 值的操作将每个元素视为单个 UTF-16 代码单元。然而,ECMAScript 不限制这些代码单元的值或关系,因此进一步解释 String 内容为 UTF-16 编码的 Unicode 代码点序列的操作必须考虑到格式不正确的子序列。这些操作对于每个数值位于从 0xD800 到 0xDBFF(由 Unicode 标准定义为leading surrogate,或更正式地称为high-surrogate code unit)的代码单元,以及每个数值位于从 0xDC00 到 0xDFFF(定义为trailing surrogate,或更正式地称为low-surrogate code unit)的代码单元使用以下规则:

  • 一个既不是前导代理对也不是后继代理对的代码单元,将被解释为具有相同值的代码点。
  • 两个代码单元的序列,其中第一个代码单元 c1前导代理对,第二个代码单元 c2后继代理对,称为代理对,解释为代码点的值为 (c1 - 0xD800) × 0x400 + (c2 - 0xDC00) + 0x10000。(参见11.1.3
  • 一个是前导代理对后继代理对的代码单元,但不是代理对的一部分,将被解释为具有相同值的代码点。

函数 String.prototype.normalize(参见22.1.3.15)可以用来显式标准化一个字符串值。String.prototype.localeCompare(参见22.1.3.12)在内部标准化字符串值,但其他操作不会隐式地标准化它们操作的字符串。操作结果除非另有说明,否则不受语言和/或地区的影响。

这种设计背后的理念是为了保持字符串的实现尽可能简单和高效。如果ECMAScript源代码文本处于规范形式C,只要它们不包含任何Unicode转义序列,字符串字面值也保证是标准化的。

在这个规范中,“字符串连接 AB 等...”(每个参数是一个字符串值、代码单元或代码单元的序列)表示的是一个字符串值,其代码单元的序列是每个参数(按顺序)的代码单元的连接(按顺序)。

短语“从 inclusiveStartexclusiveEnd子字符串”(其中 S 是一个字符串值或代码单元序列,而 inclusiveStartexclusiveEnd整数)表示由 S 的连续代码单元组成的字符串值,开始于索引 inclusiveStart 并在索引 exclusiveEnd 之前立即结束(当 inclusiveStart = exclusiveEnd 时为空字符串)。如果省略了“to”后缀,则使用 S 的长度作为 exclusiveEnd 的值。

短语“ASCII 单词字符”表示以下字符串值,它仅由 Unicode 基本拉丁语块中的每个字母和数字以及 U+005F(下划线)组成:
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_".
出于历史原因,它对各种算法具有重要意义。

6.1.4.1 StringIndexOf ( string, searchValue, fromIndex )

抽象操作 StringIndexOf 接受参数 string(一个字符串)、searchValue(一个字符串)和 fromIndex (一个非负 整数)并返回一个 整数。它在被调用时执行以下步骤:

  1. lenstring 的长度。
  2. 如果 searchValue 是空字符串且 fromIndexlen,返回 fromIndex
  3. searchLensearchValue 的长度。
  4. 对于每个 整数 i 使得 fromIndexilen - searchLen,按升序执行:
    1. candidatestringii + searchLen子字符串
    2. 如果 candidatesearchValue,返回 i
  5. 返回 -1。
注 1

如果 searchValue 是空字符串且 fromIndexstring 的长度,该算法返回 fromIndex。空字符串实际上在字符串中的每个位置都能找到,包括在最后一个码位之后。

注 2

如果 fromIndex 加上 searchValue 的长度大于 string 的长度,该算法总是返回 -1。

6.1.5 符号类型(Symbol Type)

符号类型 是可以用作对象属性键的所有非字符串值的集合(6.1.7)。

每个可能的符号值都是唯一且不可变的。

每个符号值不可变地持有一个关联的值,称为 [[Description]],它要么是 undefined,要么是一个字符串值。

6.1.5.1 众所周知的符号(Well-Known Symbols)

众所周知的符号是本规范算法明确引用的内建符号值。它们通常用作属性的键,这些属性的值作为规范算法的扩展点。除非另有说明,否则众所周知的符号值在所有realm中共享(9.3)。

在本规范中,一个众所周知的符号用 @@name 的形式表示,其中“name”是表1中列出的值之一。

表1: 众所周知的符号
规范名称 [[Description]] 值和用途
@@asyncIterator "Symbol.asyncIterator" 一个方法,返回对象的默认异步迭代器。由for-await-of语句的语义调用。
@@hasInstance "Symbol.hasInstance" 一个方法,确定构造函数对象是否将某个对象识别为其实例之一。由instanceof运算符的语义调用。
@@isConcatSpreadable "Symbol.isConcatSpreadable" 一个布尔值属性,如果为true,表示对象应通过Array.prototype.concat展平为其数组元素。
@@iterator "Symbol.iterator" 一个方法,返回对象的默认迭代器。由for-of语句的语义调用。
@@match "Symbol.match" 一个正则表达式方法,将正则表达式与字符串匹配。由String.prototype.match方法调用。
@@matchAll "Symbol.matchAll" 一个正则表达式方法,返回一个迭代器,该迭代器生成正则表达式与字符串匹配的所有结果。由String.prototype.matchAll方法调用。
@@replace "Symbol.replace" 一个正则表达式方法,替换字符串中的匹配子字符串。由String.prototype.replace方法调用。
@@search "Symbol.search" 一个正则表达式方法,返回匹配正则表达式的字符串中的索引。由String.prototype.search方法调用。
@@species "Symbol.species" 一个函数值属性,是用于创建派生对象的构造函数。
@@split "Symbol.split" 一个正则表达式方法,在匹配正则表达式的索引处分割字符串。由String.prototype.split方法调用。
@@toPrimitive "Symbol.toPrimitive" 一个方法,将对象转换为相应的原始值。由ToPrimitive抽象操作调用。
@@toStringTag "Symbol.toStringTag" 一个字符串值属性,用于创建对象的默认字符串描述。由内建方法Object.prototype.toString访问。
@@unscopables "Symbol.unscopables" 一个对象值属性,其自身和继承的属性名称是从相关对象的with环境绑定中排除的属性名称。

6.1.6 数字类型(Numeric Types)

ECMAScript 有两种内建的数字类型:Number 和 BigInt。以下抽象操作定义在这些数字类型上。“结果”列显示返回类型,并指出某些操作调用是否可能返回异常完成

表2:数字类型操作
操作 示例源码 评估语义调用... 结果
Number::unaryMinus -x 一元 - 运算符 Number
BigInt::unaryMinus BigInt
Number::bitwiseNOT ~x 按位非运算符 ( ~ ) Number
BigInt::bitwiseNOT BigInt
Number::exponentiate x ** y 幂运算符Math.pow ( base, exponent ) Number
BigInt::exponentiate 要么是包含 BigInt 的正常完成,要么是抛出完成
Number::multiply x * y 乘法运算符 Number
BigInt::multiply BigInt
Number::divide x / y 乘法运算符 Number
BigInt::divide 要么是包含 BigInt 的正常完成,要么是抛出完成
Number::remainder x % y 乘法运算符 Number
BigInt::remainder 要么是包含 BigInt 的正常完成,要么是抛出完成
Number::add x ++
++ x
x + y
后缀递增运算符, 前缀递增运算符, 和 加法运算符(+ Number
BigInt::add BigInt
Number::subtract x --
-- x
x - y
后缀递减运算符, 前缀递减运算符, 和 减法运算符(- Number
BigInt::subtract BigInt
Number::leftShift x << y 左移位运算符(<< Number
BigInt::leftShift BigInt
Number::signedRightShift x >> y 有符号右移位运算符(>> Number
BigInt::signedRightShift BigInt
Number::unsignedRightShift x >>> y The Unsigned Right Shift Operator ( >>> ) Number
BigInt::unsignedRightShift a throw completion
Number::lessThan x < y
x > y
x <= y
x >= y
关系运算符, via IsLessThan ( x, y, LeftFirst ) Boolean or undefined (for unordered inputs)
BigInt::lessThan Boolean
Number::equal x == y
x != y
x === y
x !== y
等值运算符, via IsStrictlyEqual ( x, y ) Boolean
BigInt::equal
Number::sameValue Object.is(x, y) 对象内部方法, via SameValue ( x, y ), 测试精确的值相等性 Boolean
Number::sameValueZero [x].includes(y) Array、Map和Set方法, via SameValueZero ( x, y ), 要测试值相等性,忽略 +0𝔽-0𝔽 Boolean
Number::bitwiseAND x & y 二进制按位运算符 Number
BigInt::bitwiseAND BigInt
Number::bitwiseXOR x ^ y Number
BigInt::bitwiseXOR BigInt
Number::bitwiseOR x | y Number
BigInt::bitwiseOR BigInt
Number::toString String(x) 许多表达式和内置函数, 经由 ToString ( argument ) String
BigInt::toString

由于数值类型通常不能在不损失精度或截断的情况下相互转换,ECMAScript语言不提供这些类型之间的隐式转换。在调用需要另一种类型的函数时,程序员必须显式调用 NumberBigInt 函数进行类型转换。

注意

ECMAScript 的早期和后续版本为某些运算符提供了隐式数值转换,这可能会损失精度或 截断。这些遗留的隐式转换保留了向后兼容性,但不适用于 BigInt,以减少程序员错误的可能性,并为未来版本中的泛型 值类型 留出选项。

6.1.6.1 数字类型(The Number Type)

数字类型(Number type)具有精确的 18,437,736,874,454,810,627 (即 264 - 253 + 3)个值, 表示双精度 64 位格式的 IEEE 754-2019 值,这些值按照 IEEE 二进制浮点算术标准规定。不同于 IEEE 标准的 9,007,199,254,740,990 (即 253 - 2)个“非数值(Not-a-Number)”值在 ECMAScript 中表示为单独的特殊值 NaN。 (注意,NaN 值由程序表达式 NaN 产生。)在一些实现中,外部代码可能能够检测到各种不同的非数值,但这种行为是 实现定义的; 对于 ECMAScript 代码来说,所有的 NaN 值都是无法区分的。

注意

在存储 Number 值到 ArrayBuffer(参见 25.1)或 SharedArrayBuffer(参见 25.2)后,可能观察到的位模式不一定与 ECMAScript 实现中使用的该 Number 值的内部表示相同。

还有另外两个特殊值,分别称为 positive Infinitynegative Infinity。为了简洁起见,在解释目的上,这些值也被表示为符号 +∞𝔽-∞𝔽,分别。(注意,这两个无穷大的 Number 值由程序表达式 +Infinity(或简单地 Infinity)和 -Infinity 产生。)

其余的 18,437,736,874,454,810,624(即 264 - 253)个值被称为 有限数。其中一半是正数,一半是负数;对于每个 有限 的正数 Number 值,都有一个相应的具有相同数量级的负数值。

注意,这里有一个 positive zero 和一个 negative zero。为了简洁起见,在解释目的上,这些值也被表示为符号 +0𝔽-0𝔽,分别。(注意,这两个不同的零 Number 值由程序表达式 +0(或简单地 0)和 -0 产生。)

18,437,736,874,454,810,622(即 264 - 253 - 2)个 有限 的非零值分为两种:

18,428,729,675,200,069,632(即 264 - 254)个被规范化的值,具有以下形式:

s × m × 2e

其中,s 可以是 1 或 -1,m 是一个 整数,在区间从 252(包含)到 253(不包含)之间,而 e 是一个 整数,在区间从 -1074 到 971 的 包含区间内。

剩余的 9,007,199,254,740,990(即 253 - 2)个值是非规格化的,具有以下形式:

s × m × 2e

其中,s 可以是 1 或 -1,m 是一个 整数,在区间从 0(不包含)到 252(不包含)之间,而 e 是 -1074。

注意,在 Number 类型中,所有不大于 253 的正整数和负整数都可以表示。整数 0 在 Number 类型中有两种表示形式:+0𝔽-0𝔽

一个 有限数 的“奇数有效尾数”指的是,如果它是非零的,并且用来表示它的 整数 m(以上述两种形式之一)是奇数。否则,它具有“偶数有效尾数”。 在本规范中,“表示为数值的 Number 值 for x”这一短语表示选定以下方式的 Number 值。考虑所有的 Number 类型的 有限值,从中去除 -0𝔽,并额外添加两个不可表示的值,即 21024(即 +1 × 253 × 2971)和 -21024(即 -1 × 253 × 2971)。选择这个集合中与 x 最接近的成员。如果集合中有两个值同样接近,则选择有效尾数为偶数的那个;为此,额外的两个值 21024-21024 被认为具有偶数的有效尾数。最后,如果选择了 21024,则用 +∞𝔽 替换它;如果选择了 -21024,则用 -∞𝔽 替换它;如果选择了 +0𝔽,则仅当 x < 0 时,用 -0𝔽 替换它;否则使用选择的其他值而不变。结果就是 表示为数值的 Number 值 for x。(此过程与 IEEE 754-2019 roundTiesToEven 模式的行为完全对应。)

+∞ 的 Number 值为+∞𝔽,而 -∞ 的 Number 值为-∞𝔽

一些 ECMAScript 运算符只处理特定范围内的 整数,比如从 -231231 - 1闭区间或者从 0 到 216 - 1闭区间。这些运算符接受 Number 类型的任何值,但首先将每个这样的值转换为预期范围内的 整数 值。请参阅 7.1 中的数值转换操作描述。

6.1.6.1.1 Number::unaryMinus ( x )

抽象操作 Number::unaryMinus 接受参数 x(一个 Number),并返回一个 Number。调用时执行以下步骤:

  1. 如果 xNaN,则返回 NaN
  2. 返回取反后的结果 x;即具有相同大小但相反符号的 Number。

6.1.6.1.2 Number::bitwiseNOT ( x )

抽象操作 Number::bitwiseNOT 接受参数 x(一个 Number),并返回一个 整数型 Number。调用时执行以下步骤:

  1. oldValue 为 ! ToInt32(x)。
  2. 返回对 oldValue 应用按位补码操作的结果。该结果的 数学值 正好可表示为一个32位的二进制补码字符串。

6.1.6.1.3 Number::exponentiate ( base, exponent )

抽象操作 Number::exponentiate 接受参数 base(一个 Number)和 exponent(一个 Number),并返回一个 Number。它返回一个 实现近似值,表示将 baseexponent 次幂的结果。调用时执行以下步骤:

  1. 如果 exponentNaN,则返回 NaN
  2. 如果 exponent+0𝔽-0𝔽,则返回 1𝔽
  3. 如果 baseNaN,则返回 NaN
  4. 如果 base+∞𝔽,则
    1. 如果 exponent > +0𝔽,则返回 +∞𝔽。否则,返回 +0𝔽
  5. 如果 base-∞𝔽,则
    1. 如果 exponent > +0𝔽,那么
      1. 如果 exponent 是奇数的 integral Number,则返回 -∞𝔽。否则,返回 +∞𝔽
    2. 否则,
      1. 如果 exponent 是奇数的 integral Number,则返回 -0𝔽。否则,返回 +0𝔽
  6. 如果 base+0𝔽,则
    1. 如果 exponent > +0𝔽,则返回 +0𝔽。否则,返回 +∞𝔽
  7. 如果 base-0𝔽,则
    1. 如果 exponent > +0𝔽,那么
      1. 如果 exponent 是奇数的 integral Number,则返回 -0𝔽。否则,返回 +0𝔽
    2. 否则,
      1. 如果 exponent 是奇数的 integral Number,则返回 -∞𝔽。否则,返回 +∞𝔽
  8. Assert: base 是有限数,并且不是 +0𝔽-0𝔽
  9. 如果 exponent+∞𝔽,则
    1. 如果 abs((base)) > 1,则返回 +∞𝔽
    2. 如果 abs((base)) = 1,则返回 NaN
    3. 如果 abs((base)) < 1,则返回 +0𝔽
  10. 如果 exponent-∞𝔽,则
    1. 如果 abs((base)) > 1,则返回 +0𝔽
    2. 如果 abs((base)) = 1,则返回 NaN
    3. 如果 abs((base)) < 1,则返回 +∞𝔽
  11. Assert: exponentfinite,并且不是 +0𝔽-0𝔽
  12. 如果 base < -0𝔽,并且 exponent 不是一个 integral Number,则返回 NaN
  13. 返回一个表示将 (base) 的 (exponent) 次幂的结果的 implementation-approximated 数值。
注意

base1𝔽-1𝔽,并且 exponent+∞𝔽-∞𝔽,或者当 base1𝔽exponentNaN𝔽 时,base ** exponent 的结果与 IEEE 754-2019 不同。ECMAScript 的第一版对于这个操作的结果规定为 NaN,而后来的 IEEE 754 标准修订版规定为 1𝔽。为了兼容性,保留了历史上 ECMAScript 的行为。

6.1.6.1.4 Number::multiply ( x, y )

抽象操作 Number::multiply 接受参数 x(一个 Number)和 y(一个 Number),返回一个 Number。它根据 IEEE 754-2019 的双精度二进制算术规则执行乘法运算,生成 xy 的乘积。调用时执行以下步骤:

  1. 如果 xNaN 或者 yNaN,则返回 NaN
  2. 如果 x+∞𝔽 或者 -∞𝔽,则
    1. 如果 y+0𝔽 或者 -0𝔽,则返回 NaN
    2. 如果 y > +0𝔽,则返回 x
    3. 返回 -x
  3. 如果 y+∞𝔽 或者 -∞𝔽,则
    1. 如果 x+0𝔽 或者 -0𝔽,则返回 NaN
    2. 如果 x > +0𝔽,则返回 y
    3. 返回 -y
  4. 如果 x-0𝔽,则
    1. 如果 y-0𝔽 或者 y < -0𝔽,则返回 +0𝔽
    2. 否则,返回 -0𝔽
  5. 如果 y-0𝔽,则
    1. 如果 x < -0𝔽,则返回 +0𝔽
    2. 否则,返回 -0𝔽
  6. 返回 𝔽((x) × (y))。
注意

有限精度乘法是可交换的,但不总是可结合的。

6.1.6.1.5 Number::divide ( x, y )

抽象操作 Number::divide 接受参数 x(一个 Number)和 y(一个 Number),返回一个 Number。 它根据 IEEE 754-2019 二进制双精度算术规则执行除法,产生 x 除以 y 的商。 调用时执行以下步骤:

  1. 如果 xNaN 或者 yNaN,返回 NaN
  2. 如果 x+∞𝔽 或者 -∞𝔽,则
    1. 如果 y+∞𝔽 或者 -∞𝔽,返回 NaN
    2. 如果 y+0𝔽 或者 y > +0𝔽,返回 x
    3. 返回 -x
  3. 如果 y+∞𝔽,则
    1. 如果 x+0𝔽 或者 x > +0𝔽,返回 +0𝔽。 否则,返回 -0𝔽
  4. 如果 y-∞𝔽,则
    1. 如果 x+0𝔽 或者 x > +0𝔽,返回 -0𝔽。 否则,返回 +0𝔽
  5. 如果 x+0𝔽 或者 -0𝔽,则
    1. 如果 y+0𝔽 或者 -0𝔽,返回 NaN
    2. 如果 y > +0𝔽, 返回 x
    3. 返回 -x
  6. 如果 y+0𝔽,则
    1. 如果 x > +0𝔽, 返回 +∞𝔽。否则,返回 -∞𝔽
  7. 如果 y-0𝔽,则
    1. 如果 x > +0𝔽, 返回 -∞𝔽。否则,返回 +∞𝔽
  8. 返回 𝔽((x) / (y)).

6.1.6.1.6 Number::remainder ( n, d )

抽象操作 Number::remainder 接受参数 n(一个 Number)和 d(一个 Number),返回一个 Number。 它返回其操作数的隐含除法的余数,其中 n 是被除数,d 是除数。调用时执行以下步骤:

  1. 如果 nNaN 或者 dNaN,返回 NaN
  2. 如果 n+∞𝔽 或者 -∞𝔽,返回 NaN
  3. 如果 d+∞𝔽 或者 -∞𝔽,返回 n
  4. 如果 d+0𝔽 或者 -0𝔽,返回 NaN
  5. 如果 n+0𝔽 或者 -0𝔽,返回 n
  6. Assert: ndfinite 的且非零。
  7. quotient(n) / (d)。
  8. qtruncate(quotient)。
  9. r(n) - ((d) × q)。
  10. 如果 r = 0 并且 n < -0𝔽,返回 -0𝔽
  11. 返回 𝔽(r)。
注1

在 C 和 C++ 中,取余运算符只接受整数操作数;在 ECMAScript 中,它也接受浮点操作数。

注2
浮点取余运算的结果与 % 运算符计算的“余数”操作不同,后者由 IEEE 754-2019 定义。 IEEE 754-2019 的“余数”操作从四舍五入的除法中计算余数,而不是截断的除法,因此其行为与通常的 整数 取余运算符不类似。 相反,ECMAScript 语言定义浮点操作的 % 以类似于 Java 整数 取余运算符的方式行为;这可以与 C 库函数 fmod 进行比较。

6.1.6.1.7 Number::add ( x, y )

抽象操作 Number::add 接受参数 x(一个 Number)和 y(一个 Number),返回一个 Number。它根据 IEEE 754-2019 二进制双精度算术的规则执行加法,生成其参数的和。调用时执行以下步骤:

  1. 如果 xNaN 或者 yNaN,返回 NaN
  2. 如果 x+∞𝔽 并且 y-∞𝔽,返回 NaN
  3. 如果 x-∞𝔽 并且 y+∞𝔽,返回 NaN
  4. 如果 x+∞𝔽 或者 -∞𝔽,返回 x
  5. 如果 y+∞𝔽 或者 -∞𝔽,返回 y
  6. Assert: xy 都是 有限的
  7. 如果 x-0𝔽 并且 y-0𝔽,返回 -0𝔽
  8. 返回 𝔽((x) + (y))。

有限精度加法是可交换的,但并非总是可结合的。

6.1.6.1.8 Number::subtract ( x, y )

抽象操作 Number::subtract 接受参数 x(一个 Number)和 y(一个 Number),返回一个 Number。它执行减法运算,生成其操作数的差;x 是被减数,y 是减数。调用时执行以下步骤:

  1. 返回 Number::add(x, Number::unaryMinus(y))。

总是有 x - y 的结果与 x + (-y) 相同。

6.1.6.1.9 Number::leftShift ( x, y )

抽象操作 Number::leftShift 接受参数 x(一个 Number)和 y(一个 Number),返回一个整数 Number。调用时执行以下步骤:

  1. lnum 为 ! ToInt32(x)。
  2. rnum 为 ! ToUint32(y)。
  3. shiftCount(rnum) modulo 32。
  4. 返回将 lnum 左移 shiftCount 位的结果。结果的 数学值可准确表示为一个32位二进制补码位字符串。

6.1.6.1.10 Number::signedRightShift ( x, y )

抽象操作 Number::signedRightShift 接受参数 x(一个 Number)和 y(一个 Number),返回一个整数 Number。调用时执行以下步骤:

  1. lnum 为 ! ToInt32(x)。
  2. rnum 为 ! ToUint32(y)。
  3. shiftCount(rnum) modulo 32。
  4. 返回将 lnum 右移 shiftCount 位并进行符号扩展的结果。最高有效位被传播。结果的 数学值可准确表示为一个32位二进制补码位字符串。

6.1.6.1.11 Number::unsignedRightShift ( x, y )

抽象操作 Number::unsignedRightShift 接受参数 x(一个 Number)和 y(一个 Number),返回一个整数 Number。调用时执行以下步骤:

  1. lnum 为 ! ToUint32(x)。
  2. rnum 为 ! ToUint32(y)。
  3. shiftCount(rnum) modulo 32。
  4. 返回将 lnum 右移 shiftCount 位并进行零填充的结果。空出的位将填充为零。结果的 数学值可准确表示为一个32位无符号位字符串。

6.1.6.1.12 Number::lessThan ( x, y )

抽象操作 Number::lessThan 接受参数 x(一个 Number)和 y(一个 Number),返回一个布尔值或 undefined。调用时执行以下步骤:

  1. 如果 xNaN,则返回 undefined
  2. 如果 yNaN,则返回 undefined
  3. 如果 x 等于 y,则返回 false
  4. 如果 x+0𝔽 并且 y-0𝔽,则返回 false
  5. 如果 x-0𝔽 并且 y+0𝔽,则返回 false
  6. 如果 x+∞𝔽,则返回 false
  7. 如果 y+∞𝔽,则返回 true
  8. 如果 y-∞𝔽,则返回 false
  9. 如果 x-∞𝔽,则返回 true
  10. Assert: xy 都是 finite
  11. 如果 (x) 小于 (y),则返回 true。否则,返回 false

6.1.6.1.13 Number::equal ( x, y )

抽象操作 Number::equal 接受参数 x(一个 Number)和 y(一个 Number),返回一个布尔值。调用时执行以下步骤:

  1. 如果 xNaN,则返回 false
  2. 如果 yNaN,则返回 false
  3. 如果 x 等于 y,则返回 true
  4. 如果 x+0𝔽 并且 y-0𝔽,则返回 true
  5. 如果 x-0𝔽 并且 y+0𝔽,则返回 true
  6. 返回 false

6.1.6.1.14 Number::sameValue ( x, y )

抽象操作 Number::sameValue 接受参数 x(一个 Number)和 y(一个 Number),返回一个布尔值。调用时执行以下步骤:

  1. 如果 xNaN 并且 yNaN,则返回 true
  2. 如果 x+0𝔽 并且 y-0𝔽,则返回 false
  3. 如果 x-0𝔽 并且 y+0𝔽,则返回 false
  4. 如果 x 等于 y,则返回 true
  5. 返回 false

6.1.6.1.15 Number::sameValueZero ( x, y )

抽象操作 Number::sameValueZero 接受参数 x(一个 Number)和 y(一个 Number),返回一个布尔值。调用时执行以下步骤:

  1. 如果 xNaN 并且 yNaN,则返回 true
  2. 如果 x+0𝔽 并且 y-0𝔽,则返回 true
  3. 如果 x-0𝔽 并且 y+0𝔽,则返回 true
  4. 如果 x 等于 y,则返回 true
  5. 返回 false

6.1.6.1.16 Number::NumberBitwiseOp ( op, x, y )

抽象操作 Number::NumberBitwiseOp 接受参数 op&^|)、x(一个 Number)和 y(一个 Number),返回一个 integral Number。调用时执行以下步骤:

  1. lnum 为 ! ToInt32(x).
  2. rnum 为 ! ToInt32(y).
  3. lbits 为表示 (lnum) 的 32 位二进制补码位字符串。
  4. rbits 为表示 (rnum) 的 32 位二进制补码位字符串。
  5. 如果 op&,则
    1. result 为对 lbitsrbits 执行按位与操作的结果。
  6. 否则,如果 op^,则
    1. result 为对 lbitsrbits 执行按位异或(XOR)操作的结果。
  7. 否则,
    1. Assert:断言 op|
    2. result 为对 lbitsrbits 执行按位或操作的结果。
  8. 返回由 32 位二进制补码位字符串 result 表示的 Number value forinteger

6.1.6.1.17 Number::bitwiseAND ( x, y )

抽象操作 Number::bitwiseAND 接受参数 x(一个 Number)和 y(一个 Number),返回一个 integral Number。调用时执行以下步骤:

  1. 返回 NumberBitwiseOp(&, x, y).

6.1.6.1.18 Number::bitwiseXOR ( x, y )

抽象操作 Number::bitwiseXOR 接受参数 x(一个 Number)和 y(一个 Number),返回一个 integral Number。调用时执行以下步骤:

  1. 返回 NumberBitwiseOp(^, x, y).

6.1.6.1.19 Number::bitwiseOR ( x, y )

抽象操作 Number::bitwiseOR 接受参数 x(一个 Number)和 y(一个 Number),返回一个 integral Number。调用时执行以下步骤:

  1. 返回 NumberBitwiseOp(|, x, y).

6.1.6.1.20 Number::toString ( x, radix )

抽象操作 Number::toString 接受参数 x(一个数字)和 radix(一个在 2 到 36 之间的整数),并返回一个字符串。它使用以 radix 为基数的进位制系统将 x 表示为字符串。使用基数 r 表示数字时所用的数字取自 "0123456789abcdefghijklmnopqrstuvwxyz" 的前 r 个字符。数值大小大于或等于 1𝔽 的数字表示永远不会包含前导零。它在被调用时执行以下步骤:

  1. 如果 xNaN,返回 "NaN"
  2. 如果 x+0𝔽-0𝔽,返回 "0"
  3. 如果 x < -0𝔽,返回 字符串连接"-"Number::toString(-x, radix)。
  4. 如果 x+∞𝔽,返回 "Infinity"
  5. nks整数,使得 k ≥ 1,radixk - 1s < radixk𝔽(s × radixn - k) 是 x,并且 k 尽可能小。注意,k 是使用基数 radix 表示 s 的数字个数,s 不能被 radix 整除,并且 s 的最低有效位不一定由这些条件唯一确定。
  6. 如果 radix ≠ 10 或 n包含区间 从 -5 到 21,那么
    1. 如果 nk,那么
      1. 返回 字符串连接
        • 使用基数 radix 表示 sk 位数字的代码单元
        • n - k 个代码单元 0x0030 (DIGIT ZERO)
    2. 否则如果 n > 0,那么
      1. 返回 字符串连接
        • 使用基数 radix 表示 s 的最高有效 n 位数字的代码单元
        • 代码单元 0x002E (FULL STOP)
        • 使用基数 radix 表示 s 的剩余 k - n 位数字的代码单元
    3. 否则,
      1. 断言n ≤ 0。
      2. 返回 字符串连接
        • 代码单元 0x0030 (DIGIT ZERO)
        • 代码单元 0x002E (FULL STOP)
        • -n 个代码单元 0x0030 (DIGIT ZERO)
        • 使用基数 radix 表示 sk 位数字的代码单元
  7. 注意:在这种情况下,输入将使用科学 E 表示法表示,例如 1.2e+3
  8. 断言radix 是 10。
  9. 如果 n < 0,那么
    1. exponentSign 为代码单元 0x002D (HYPHEN-MINUS)。
  10. 否则,
    1. exponentSign 为代码单元 0x002B (PLUS SIGN)。
  11. 如果 k = 1,那么
    1. 返回 字符串连接
      • s 的单个数字的代码单元
      • 代码单元 0x0065 (LATIN SMALL LETTER E)
      • exponentSign
      • 十进制表示的 abs(n - 1)
  12. 返回 字符串连接
    • 十进制表示的 s 的最高有效位的代码单元
    • 代码单元 0x002E (FULL STOP)
    • 十进制表示的 s 的剩余 k - 1 位数字的代码单元
    • 代码单元 0x0065 (LATIN SMALL LETTER E)
    • exponentSign
    • 十进制表示的 abs(n - 1)
注意 1

以下观察可能对实现有指导作用,但不是本标准规范性要求的一部分:

  • 如果 x 是除 -0𝔽 以外的任何数字值,那么 ToNumber(ToString(x)) 是 x。
  • s 的最低有效位并不总是由步骤 5 中列出的要求唯一确定。
注意 2

对于提供比上述规则更精确转换的实现,建议使用以下替代版本的步骤 5 作为指导:

  1. nks整数,使得 k ≥ 1,radixk - 1s < radixk𝔽(s × radixn - k) 是 x,并且 k 尽可能小。如果有多个可能的 s 值,选择使 s × radixn - k 最接近 (x) 的 s 值。如果有两个这样的可能值,选择偶数的那一个。注意,k 是使用基数 radix 表示 s 的数字个数,并且 s 不能被 radix 整除。
注意 3

ECMAScript 的实现者可能会发现 David M. Gay 撰写的关于浮点数二进制到十进制转换的论文和代码很有用:

Gay, David M. 正确舍入的二进制-十进制和十进制-二进制转换。数值分析,手稿 90-10。AT&T 贝尔实验室(新泽西州默里山)。1990 年 11 月 30 日。 可在
http://ampl.com/REFS/abstracts.html#rounding 获取。 相关代码可在
http://netlib.sandia.gov/fp/dtoa.c
http://netlib.sandia.gov/fp/g_fmt.c 获取,并且可能在各个 netlib 镜像站点上找到。

6.1.6.2 BigInt 类型

BigInt 类型 表示一个 整数 值。该值可以是任意大小,并不限于特定的位宽。通常情况下,除非另有说明,操作旨在返回基于数学的精确答案。对于二进制操作,BigInt 表现为二进制补码字符串,负数被视为在其左侧有无限多的设置位。

6.1.6.2.1 BigInt::unaryMinus ( x )

抽象操作 BigInt::unaryMinus 接受参数 x(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:

  1. 如果 x0,返回 0
  2. 返回 -x

6.1.6.2.2 BigInt::bitwiseNOT ( x )

抽象操作 BigInt::bitwiseNOT 接受参数 x(一个 BigInt)并返回一个 BigInt。 它返回 x 的按位取反。它在被调用时执行以下步骤:

  1. 返回 -x - 1

6.1.6.2.3 BigInt::exponentiate ( base, exponent )

抽象操作 BigInt::exponentiate 接受参数 base(一个 BigInt)和 exponent(一个 BigInt),并返回一个包含 BigInt 的正常完成或抛出完成。它在被调用时执行以下步骤:

  1. 如果 exponent < 0,抛出一个 RangeError 异常。
  2. 如果 base0exponent0,返回 1
  3. 返回 baseexponent 次方。

6.1.6.2.4 BigInt::multiply ( x, y )

抽象操作 BigInt::multiply 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:

  1. 返回 x × y
注意
即使结果的位宽比输入大得多,也会给出精确的数学答案。

6.1.6.2.5 BigInt::divide ( x, y )

抽象操作 BigInt::divide 接受参数 x(一个 BigInt)和 y(一个 BigInt),并返回一个包含 BigInt 的正常完成或抛出完成。它在被调用时执行以下步骤:

  1. 如果 y0,抛出一个 RangeError 异常。
  2. quotient(x) / (y)。
  3. 返回 (truncate(quotient))。

6.1.6.2.6 BigInt::remainder ( n, d )

抽象操作 BigInt::remainder 接受参数 n(一个 BigInt)和 d(一个 BigInt),并返回一个 正常完成包含一个 BigInt 或一个 抛出完成。它在调用时执行以下步骤:

  1. 如果 d0,抛出一个 RangeError 异常。
  2. 如果 n0,返回 0
  3. quotient(n) / (d)。
  4. q(截断(quotient))。
  5. 返回 n - (d × q)。
注意
结果的符号与被除数的符号相同。

6.1.6.2.7 BigInt::add ( x, y )

抽象操作 BigInt::add 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:

  1. 返回 x + y

6.1.6.2.8 BigInt::subtract ( x, y )

抽象操作 BigInt::subtract 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:

  1. 返回 x - y

6.1.6.2.9 BigInt::leftShift ( x, y )

抽象操作 BigInt::leftShift 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:

  1. 如果 y < 0,则
    1. 返回 (floor((x) / 2-(y))).
  2. 返回 x × 2y.
注意
这里的语义应该等同于按位左移,将 BigInt 视为无限长度的二进制补码数字字符串。

6.1.6.2.10 BigInt::signedRightShift ( x, y )

抽象操作 BigInt::signedRightShift 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:

  1. 返回 BigInt::leftShift(x, -y).

6.1.6.2.11 BigInt::unsignedRightShift ( x, y )

抽象操作 BigInt::unsignedRightShift 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 抛出完成记录。它在被调用时执行以下步骤:

  1. 抛出一个 TypeError 异常。

6.1.6.2.12 BigInt::lessThan ( x, y )

抽象操作 BigInt::lessThan 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个布尔值。它在被调用时执行以下步骤:

  1. 如果 (x) < (y),返回 true;否则返回 false

6.1.6.2.13 BigInt::equal ( x, y )

抽象操作 BigInt::equal 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个布尔值。它在被调用时执行以下步骤:

  1. 如果 (x) = (y), 返回 true;否则返回 false

6.1.6.2.14 BinaryAnd ( x, y )

抽象操作 BinaryAnd 接受参数 x(0 或 1)和 y(0 或 1)并返回 0 或 1。它在被调用时执行以下步骤:

  1. 如果 x = 1 且 y = 1,返回 1。
  2. 否则,返回 0。

6.1.6.2.15 BinaryOr ( x, y )

抽象操作 BinaryOr 接受参数 x(0 或 1)和 y(0 或 1)并返回 0 或 1。它在被调用时执行以下步骤:

  1. 如果 x = 1 或 y = 1,返回 1。
  2. 否则,返回 0。

6.1.6.2.16 BinaryXor ( x, y )

抽象操作 BinaryXor 接受参数 x(0 或 1)和 y(0 或 1)并返回 0 或 1。它在被调用时执行以下步骤:

  1. 如果 x = 1 且 y = 0,返回 1。
  2. 否则如果 x = 0 且 y = 1,返回 1。
  3. 否则,返回 0。

6.1.6.2.17 BigInt位运算 ( op, x, y )

抽象操作 BigInt位运算 接受参数 op&^|)、x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在被调用时执行以下步骤:

  1. x 设置为 (x)。
  2. y 设置为 (y)。
  3. result 为 0。
  4. shift 为 0。
  5. 重复,直到 (x = 0 或 x = -1) 和 (y = 0 或 y = -1),
    1. xDigitx 取模 2。
    2. yDigity 取模 2。
    3. 如果 op&,那么
      1. result 设置为 result + 2shift × 按位与(xDigit, yDigit)。
    4. 否则如果 op|,那么
      1. result 设置为 result + 2shift × 按位或(xDigit, yDigit)。
    5. 否则
      1. 断言: op^
      2. result 设置为 result + 2shift × 按位异或(xDigit, yDigit)。
    6. shift 设置为 shift + 1。
    7. x 设置为 (x - xDigit) / 2。
    8. y 设置为 (y - yDigit) / 2。
  6. 如果 op&,那么
    1. tmp按位与(x 取模 2, y 取模 2)。
  7. 否则如果 op|,那么
    1. tmp按位或(x 取模 2, y 取模 2)。
  8. 否则
    1. 断言: op^
    2. tmp按位异或(x 取模 2, y 取模 2)。
  9. 如果 tmp ≠ 0,那么
    1. result 设置为 result - 2shift
    2. 注意:这扩展了符号位。
  10. 返回 BigInt 值 for result

6.1.6.2.18 BigInt::bitwiseAND ( x, y )

抽象操作 BigInt::bitwiseAND 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在调用时执行以下步骤:

  1. 返回 BigIntBitwiseOp(&, x, y)。

6.1.6.2.19 BigInt::bitwiseXOR ( x, y )

抽象操作 BigInt::bitwiseXOR 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在调用时执行以下步骤:

  1. 返回 BigIntBitwiseOp(^, x, y)。

6.1.6.2.20 BigInt::bitwiseOR ( x, y )

抽象操作 BigInt::bitwiseOR 接受参数 x(一个 BigInt)和 y(一个 BigInt)并返回一个 BigInt。它在调用时执行以下步骤:

  1. 返回 BigIntBitwiseOp(|, x, y)。

6.1.6.2.21 BigInt::toString ( x, radix )

抽象操作 BigInt::toString 接受参数 x(一个 BigInt)和 radix(一个在 2 到 36 之间的整数)并返回一个字符串。它使用基数 radixx 表示为字符串。使用基数 r 表示 BigInt 的数字取自 "0123456789abcdefghijklmnopqrstuvwxyz" 的前 r 个码元。除了 0 之外的 BigInt 表示永远不会包含前导零。它在调用时执行以下步骤:

  1. 如果 x < 0,返回 字符串连接"-"BigInt::toString(-x, radix)。
  2. 返回使用基数 radix 表示 x 的字符串值。

6.1.7 对象类型

每个 对象类型 的实例,也简称为“一个对象”,表示一个属性的集合。每个属性要么是一个数据属性,要么是一个访问器属性:

  • 一个 数据属性 将一个键值与一个 ECMAScript 语言值 和一个布尔属性集合关联起来。
  • 一个 访问器属性 将一个键值与一个或两个访问器函数以及一个布尔属性集合关联起来。访问器函数用于存储或检索与该属性相关联的 ECMAScript 语言值

对象的属性使用属性键唯一标识。一个 属性键 要么是一个字符串,要么是一个符号。所有字符串和符号,包括空字符串,都可以作为属性键。一个 属性名 是一个 字符串 的属性键。

一个 整数索引 是一个 属性名 n,使得 CanonicalNumericIndexString(n) 返回一个在 包含区间+0𝔽𝔽(253 - 1) 内的 整数。一个 数组索引 是一个 整数索引 n,使得 CanonicalNumericIndexString(n) 返回一个在 包含区间+0𝔽𝔽(232 - 2) 内的 整数

注意

每个非负的 安全整数 都有一个对应的 整数索引。除了 232 - 1 之外的每个 32 位 无符号 整数 都有一个对应的 数组索引"-0" 既不是一个 整数索引 也不是 数组索引

属性键用于访问属性和它们的值。属性访问有两种类型:获取设置,分别对应于值的检索和赋值。通过获取和设置访问的属性包括 自有属性继承属性。继承属性可能是关联对象的自有属性或继承属性。每个对象的自有属性必须具有与其他自有属性不同的键值。

所有对象在逻辑上都是属性的集合,但有多种形式的对象,它们的属性访问和操作语义不同。请参见 6.1.7.2 以了解多种形式的对象的定义。

此外,一些对象是可调用的;这些被称为函数或 函数对象,并在下面进一步描述。ECMAScript 中的所有函数都是 Object 类型的成员。

6.1.7.1 属性属性

属性用于在本规范中定义和解释对象属性的状态,如 表 3 所述。除非明确指定,每个属性的初始值为其默认值。

表 3: 对象属性的属性
属性名称 存在的属性类型 值域 默认值 描述
[[Value]] 数据属性 ECMAScript 语言值 undefined 通过获取属性访问检索到的值。
[[Writable]] 数据属性 布尔值 false 如果为 false,尝试通过 ECMAScript 代码更改属性的 [[Value]] 属性将不会成功。
[[Get]] 访问器属性 对象或 undefined undefined 如果值 是一个对象,它必须是一个 函数对象。函数的 [[Call]] 内部方法(表 5)在每次执行属性获取访问时被调用,不带参数。
[[Set]] 访问器属性 对象或 undefined undefined 如果值 是一个对象,它必须是一个 函数对象。函数的 [[Call]] 内部方法(表 5)在每次执行属性设置访问时被调用,带有一个参数,即被赋的值。属性 [[Set]] 内部方法的效果可能,但不是必须,影响后续调用属性 [[Get]] 内部方法返回的值。
[[Enumerable]] 数据属性访问器属性 一个布尔值 false 如果 true,该属性将通过 for-in 枚举(见 14.7.5)进行枚举。 否则,该属性被称为不可枚举。
[[Configurable]] 数据属性访问器属性 一个布尔值 false 如果 false,尝试删除该属性,将其从 数据属性 变为 访问器属性 或 从 访问器属性 变为 数据属性,或对其属性进行任何更改(除了替换现有的 [[Value]] 或将 [[Writable]] 设置为 false)都将失败。

6.1.7.2 对象内部方法和内部槽

在 ECMAScript 中,对象的实际语义是通过称为 内部方法 的算法指定的。每个 ECMAScript 引擎中的对象都与一组内部方法相关联,这些方法定义了其运行时行为。这些内部方法不是 ECMAScript 语言的一部分。它们纯粹是为了说明目的而由本规范定义的。然而,ECMAScript 实现中的每个对象必须按照与其相关联的内部方法指定的行为方式行事。实现的具体方式由实现决定。

内部方法名称是多态的。这意味着不同的对象值在调用相同的内部方法名称时可能会执行不同的算法。实际调用内部方法的对象是调用的“目标”。如果在运行时,算法的实现尝试使用对象不支持的内部方法,则会抛出 TypeError 异常。

内部槽对应于与对象相关联并被各种 ECMAScript 规范算法使用的内部状态。内部槽不是对象属性,也不会被继承。 根据特定的内部槽规范,这种状态可能由任何 ECMAScript 语言类型 或特定的 ECMAScript 规范类型值组成。除非另有明确说明,内部槽作为创建对象过程的一部分进行分配,并且不能动态添加到对象中。除非另有说明,内部槽的初始值为 undefined。本规范中的各种算法创建具有内部槽的对象。然而,ECMAScript 语言没有直接的方法将内部槽与对象关联起来。

所有对象都有一个名为 [[PrivateElements]] 的内部槽,它是一个 ListPrivateElements。这个 List 表示对象的私有字段、方法和访问器的值。最初,它是一个空的 List

内部方法和内部槽在本规范中使用双括号 [[ ]] 括起来的名称进行标识。

表 4 总结了本规范使用的适用于所有由 ECMAScript 代码创建或操作的对象的 基本内部方法。每个对象都必须有所有基本内部方法的算法。然而,并非所有对象都必须对这些方法使用相同的算法。

一个 普通对象 是满足以下所有条件的对象:

  • 对于 表 4 中列出的内部方法,对象使用 10.1 中定义的那些。
  • 如果对象具有 [[Call]] 内部方法,它使用 10.2.110.3.1 中定义的其中之一。
  • 如果对象具有 [[Construct]] 内部方法,它使用 10.2.210.3.2 中定义的其中之一。

一个 外来对象 是一个不是 普通对象 的对象。

本规范通过这些对象的内部方法识别不同种类的 外来对象。一个对象在行为上等同于某种 外来对象(例如 数组外来对象绑定函数外来对象),但并不具有为该种类指定的相同内部方法集合,则不被识别为该种类的 外来对象

表 4 和其他类似表格的“签名”列描述了每个内部方法的调用模式。调用模式总是包括一个括号括起来的描述性参数名称列表。如果参数名称与 ECMAScript 类型名称相同,则该名称描述参数值的所需类型。如果内部方法显式返回一个值,其参数列表后跟符号“→”和返回值的类型名称。签名中使用的类型名称指的是第 6 条中定义的类型,增加了以下附加名称。“any”表示该值可以是任何 ECMAScript 语言类型

除了其参数外,内部方法总是可以访问作为方法调用目标的对象。

内部方法隐式返回一个 完成记录,要么是一个 正常完成,它包装了调用模式中显示的返回类型的值,要么是一个 抛出完成

表 4: 基本内部方法
内部方法 签名 描述
[[GetPrototypeOf]] ( ) Object | Null 确定为该对象提供继承属性的对象。null 值表示没有继承属性。
[[SetPrototypeOf]] (Object | Null) Boolean 将该对象与提供继承属性的另一个对象关联。传递 null 表示没有继承属性。返回 true 表示操作成功完成,或 false 表示操作不成功。
[[IsExtensible]] ( ) Boolean 确定是否允许向该对象添加更多属性。
[[PreventExtensions]] ( ) Boolean 控制是否可以向该对象添加新属性。返回 true 如果操作成功,或 false 如果操作不成功。
[[GetOwnProperty]] (propertyKey) Undefined | 属性描述符 返回该对象自身属性的 属性描述符,其键为 propertyKey,或 undefined 如果没有这样的属性。
[[DefineOwnProperty]] (propertyKey, 属性描述符) Boolean 创建或修改自身属性,其键为 propertyKey,具有 属性描述符 描述的状态。返回 true 如果属性成功创建/更新,或 false 如果属性无法创建或更新。
[[HasProperty]] (propertyKey) Boolean 返回一个布尔值,指示该对象是否已经具有键为 propertyKey 的自身或继承属性。
[[Get]] (propertyKey, Receiver) any 从该对象返回键为 propertyKey 的属性的值。如果需要执行 ECMAScript 代码来检索属性值,Receiver 用作评估代码时的 this 值。
[[Set]] (propertyKey, value, Receiver) Boolean 将键为 propertyKey 的属性的值设置为 value。如果需要执行 ECMAScript 代码来设置属性值,Receiver 用作评估代码时的 this 值。返回 true 如果属性值已设置,或 false 如果无法设置。
[[Delete]] (propertyKey) Boolean 从该对象中删除键为 propertyKey 的自身属性。如果属性未删除且仍存在,返回 false。如果属性已删除或不存在,返回 true
[[OwnPropertyKeys]] ( ) List of 属性键 返回一个 List,其元素是对象的所有自身 属性键

表 5 总结了可能被调用为函数的对象支持的额外基本内部方法。一个 函数对象 是支持 [[Call]] 内部方法的对象。一个 构造函数 是支持 [[Construct]] 内部方法的对象。每个支持 [[Construct]] 的对象必须支持 [[Call]];也就是说,每个 构造函数 必须是一个 函数对象。因此,一个 构造函数 也可以被称为 构造函数 函数构造函数 函数对象

表 5: 函数对象的额外基本内部方法
内部方法 签名 描述
[[Call]] (any, a List of any) any 执行与此对象关联的代码。通过函数调用表达式调用。内部方法的参数是一个 this 值和一个 List,其元素是通过调用表达式传递给函数的参数。实现此内部方法的对象是 可调用的
[[Construct]] (a List of any, Object) Object 创建一个对象。通过 new 运算符或 super 调用调用。内部方法的第一个参数是一个 List,其元素是 构造函数 调用或 super 调用的参数。第二个参数是最初应用 new 运算符的对象。实现此内部方法的对象称为 构造函数。一个 函数对象 不一定是 构造函数,并且这些非 构造函数 函数对象 没有 [[Construct]] 内部方法。

普通对象和标准外来对象的基本内部方法的语义在第 10 条中指定。如果实现不支持外来对象的任何指定内部方法的使用,则必须在尝试时抛出 TypeError 异常。

6.1.7.3 基本内部方法的不变性

ECMAScript引擎中对象的内部方法必须符合下面指定的不变性列表。普通ECMAScript对象以及本规范中的所有标准外来对象都保持这些不变性。ECMAScript代理对象通过在[[ProxyHandler]] 对象上调用的陷阱结果上进行运行时检查来保持这些不变性。

任何实现提供的外来对象也必须为这些对象保持这些不变性。违反这些不变性可能导致ECMAScript代码行为不可预测并产生安全问题。然而,违反这些不变性绝不能损害实现的内存安全。

实现不得以任何方式允许绕过这些不变性,例如通过提供实现基本内部方法功能的替代接口而不强制执行其不变性。

定义:

  • 内部方法的目标是调用内部方法的对象。
  • 如果目标对象的[[IsExtensible]]内部方法返回false,或者其[[PreventExtensions]]内部方法返回true,则该目标是不可扩展的
  • 不存在的属性是不可扩展目标对象上不存在的自有属性。
  • 所有对SameValue的引用均根据SameValue算法的定义。

返回值:

任何内部方法返回的值必须是一个Completion Record,具有以下任一形式:

  • [[Type]] = normal[[Target]] = empty,和[[Value]] = 该内部方法显示的“正常返回类型”的值,或
  • [[Type]] = throw[[Target]] = empty,和[[Value]] = 任何ECMAScript语言值
注意 1

内部方法不得返回continue completionbreak completionreturn completion

[[GetPrototypeOf]] ( )

  • 正常返回类型是Object或Null。
  • 如果目标对象是不可扩展的,并且[[GetPrototypeOf]]返回一个值V,那么任何未来的[[GetPrototypeOf]]调用应返回与V相同的SameValue
注意 2

一个对象的原型链应该具有有限长度(即,从任何对象开始,递归地将其[[GetPrototypeOf]]内部方法应用于其结果最终应导致值null)。然而,如果原型链包括任何不使用普通对象定义的[[GetPrototypeOf]]外来对象,则此要求作为对象级别的不变性是不可执行的。这样的循环原型链可能会在访问对象属性时导致无限循环。

[[SetPrototypeOf]] ( V )

  • 正常返回类型是Boolean。
  • 如果目标对象是不可扩展的,[[SetPrototypeOf]]必须返回false,除非V与目标对象观察到的[[GetPrototypeOf]]值相同SameValue

[[IsExtensible]] ( )

  • 正常返回类型是Boolean。
  • 如果[[IsExtensible]]返回false,所有未来对该目标对象的[[IsExtensible]]调用必须返回false

[[PreventExtensions]] ( )

  • 正常返回类型是Boolean。
  • 如果[[PreventExtensions]]返回true,所有未来对该目标对象的[[IsExtensible]]调用必须返回false,并且该目标对象现在被认为是不可扩展的。

[[GetOwnProperty]] ( P )

  • 正常返回类型是Property Descriptor或Undefined。
  • 如果返回值的类型是Property Descriptor,则返回值必须是一个完全填充的Property Descriptor
  • 如果P被描述为不可配置、不可写的自有数据属性,所有未来对[[GetOwnProperty]] ( P )的调用必须返回Property Descriptor,其[[Value]]P[[Value]]属性相同SameValue
  • 如果P的除了[[Writable]][[Value]]之外的属性可能会随时间变化,或者如果该属性可能会被删除,那么P[[Configurable]]属性必须是true
  • 如果[[Writable]]属性可能从false变为true,那么[[Configurable]]属性必须是true
  • 如果目标对象是不可扩展的且P不存在,那么所有未来对该目标对象的[[GetOwnProperty]] ( P )调用必须将P描述为不存在(即[[GetOwnProperty]] ( P )必须返回undefined)。
注意 3

由于第三个不变性的结果,如果一个属性被描述为数据属性并且它可能会随时间返回不同的值,那么[[Writable]][[Configurable]]属性中至少有一个必须是true,即使没有通过其他基本内部方法暴露改变值的机制。

[[DefineOwnProperty]] ( P, Desc )

  • 正常返回类型是Boolean。
  • [[DefineOwnProperty]]必须返回false,如果P之前已被观察为目标对象的不可配置自有属性,除非:
    1. P是一个可写的数据属性。一个不可配置的可写数据属性可以被改变为一个不可配置的不可写数据属性
    2. Desc的所有属性与P的属性相同SameValue
  • [[DefineOwnProperty]] ( P, Desc ) 必须返回false,如果目标对象是不可扩展的且P是一个不存在的自有属性。也就是说,一个不可扩展的目标对象不能被扩展新的属性。

[[HasProperty]] ( P )

  • 正常返回类型是Boolean。
  • 如果P之前已被观察为目标对象的不可配置自有数据或访问器属性[[HasProperty]]必须返回true

[[Get]] ( P, Receiver )

  • 正常返回类型是任何ECMAScript语言类型
  • 如果P之前已被观察为目标对象的不可配置、不可写的自有数据属性,其值为V,那么[[Get]]必须返回与V相同的SameValue
  • 如果P之前已被观察为目标对象的不可配置自有访问器属性,其[[Get]]属性为undefined[[Get]]操作必须返回undefined

[[Set]] ( P, V, Receiver )

  • 正常返回类型是Boolean。
  • 如果P之前已被观察为目标对象的不可配置、不可写的自有数据属性,那么[[Set]]必须返回false,除非VP[[Value]]属性相同SameValue
  • 如果P之前已被观察为目标对象的不可配置自有访问器属性,其[[Set]]属性为undefined[[Set]]操作必须返回false

[[Delete]] ( P )

  • 正常返回类型是Boolean。
  • 如果P之前已被观察为目标对象的不可配置自有数据或访问器属性[[Delete]]必须返回false

[[OwnPropertyKeys]] ( )

  • 正常返回类型是List
  • 返回的List不得包含任何重复条目。
  • 返回的List的每个元素的类型必须是String或Symbol。
  • 返回的List必须至少包含所有之前观察到的不可配置自有属性的键。
  • 如果目标对象是不可扩展的,返回的List必须仅包含目标对象的所有自有属性的键,这些属性可通过[[GetOwnProperty]]观察到。

[[Call]] ( )

[[Construct]] ( )

  • 正常返回类型是Object。
  • 目标对象还必须具有[[Call]]内部方法。

6.1.7.4 众所周知的内在对象

众所周知的内在对象是内置对象,它们在本规范的算法中被明确引用,并且通常具有与领域相关的身份。除非另有说明,每个内在对象实际上对应于一组类似的对象,每个领域一个。

在本规范中,诸如%name%的引用意味着与当前领域相关联的内在对象,对应于该名称。诸如%name.a.b%的引用意味着,在任何ECMAScript代码被评估之前,访问内在对象%name%的"a"属性的"b"属性。当前领域及其内在对象的确定在9.4中描述。众所周知的内在对象列在表6中。

表 6:众所周知的内置对象
内置名称 全局名称 ECMAScript 语言关联
%AggregateError% AggregateError AggregateError 构造函数 (20.5.7.1)
%Array% Array Array 构造函数 (23.1.1)
%ArrayBuffer% ArrayBuffer ArrayBuffer 构造函数 (25.1.4)
%ArrayIteratorPrototype% 数组迭代器对象的原型 (23.1.5)
%AsyncFromSyncIteratorPrototype% async-from-sync 迭代器对象的原型 (27.1.4)
%AsyncFunction% 异步函数对象的构造函数 (27.7.1)
%AsyncGeneratorFunction% 异步迭代器对象的构造函数 (27.4.1)
%AsyncIteratorPrototype% 所有标准内置异步迭代器对象间接继承的对象
%Atomics% Atomics Atomics 对象 (25.4)
%BigInt% BigInt BigInt 构造函数 (21.2.1)
%BigInt64Array% BigInt64Array BigInt64Array 构造函数 (23.2)
%BigUint64Array% BigUint64Array BigUint64Array 构造函数 (23.2)
%Boolean% 布尔值 布尔值 构造函数 (20.3.1)
%DataView% 数据视图 数据视图 构造函数 (25.3.2)
%Date% Date Date 构造函数 (21.4.2)
%decodeURI% decodeURI decodeURI 函数 (19.2.6.1)
%decodeURIComponent% decodeURIComponent decodeURIComponent 函数 (19.2.6.2)
%encodeURI% encodeURI encodeURI 函数 (19.2.6.3)
%encodeURIComponent% encodeURIComponent encodeURIComponent 函数 (19.2.6.4)
%Error% Error Error 构造函数 (20.5.1)
%eval% eval eval 函数 (19.2.1)
%EvalError% EvalError EvalError 构造函数 (20.5.5.1)
%FinalizationRegistry% FinalizationRegistry FinalizationRegistry 构造函数 (26.2.1)
%Float32Array% Float32Array Float32Array 构造函数 (23.2)
%Float64Array% Float64Array Float64Array 构造函数 (23.2)
%ForInIteratorPrototype% For-In 迭代器对象的原型 (14.7.5.10)
%Function% Function Function 构造函数 (20.2.1)
%GeneratorFunction% 生成器的构造函数 (27.3.1)
%Int8Array% Int8Array Int8Array 构造函数 (23.2)
%Int16Array% Int16Array Int16Array 构造函数 (23.2)
%Int32Array% Int32Array Int32Array 构造函数 (23.2)
%isFinite% isFinite isFinite 函数 (19.2.2)
%isNaN% isNaN isNaN 函数 (19.2.3)
%IteratorPrototype% 所有标准内置迭代器对象间接继承的对象
%JSON% JSON JSON 对象 (25.5)
%Map% Map Map 构造函数 (24.1.1)
%MapIteratorPrototype% Map 迭代器对象的原型 (24.1.5)
%Math% Math Math 对象 (21.3)
%Number% Number Number 构造函数 (21.1.1)
%Object% Object Object 构造函数 (20.1.1)
%parseFloat% parseFloat parseFloat 函数 (19.2.4)
%parseInt% parseInt parseInt 函数 (19.2.5)
%Promise% Promise Promise 构造函数 (27.2.3)
%Proxy% Proxy Proxy 构造函数 (28.2.1)
%RangeError% RangeError RangeError 构造函数 (20.5.5.2)
%ReferenceError% ReferenceError ReferenceError 构造函数 (20.5.5.3)
%Reflect% Reflect Reflect 对象 (28.1)
%RegExp% RegExp RegExp 构造函数 (22.2.4)
%RegExpStringIteratorPrototype% 正则表达式字符串迭代器对象的原型 (22.2.9)
%Set% Set Set 构造函数 (24.2.1)
%SetIteratorPrototype% Set 迭代器对象的原型 (24.2.5)
%SharedArrayBuffer% SharedArrayBuffer SharedArrayBuffer 构造函数 (25.2.3)
%String% String String 构造函数 (22.1.1)
%StringIteratorPrototype% 字符串迭代器对象的原型 (22.1.5)
%Symbol% Symbol Symbol 构造函数 (20.4.1)
%SyntaxError% SyntaxError SyntaxError 构造函数 (20.5.5.4)
%ThrowTypeError% 一个 函数对象,它会无条件抛出一个新的 %TypeError% 实例
%TypedArray% 所有类型化数组 构造函数 的超类 (23.2.1)
%TypeError% TypeError TypeError 构造函数 (20.5.5.5)
%Uint8Array% Uint8Array Uint8Array 构造函数 (23.2)
%Uint8ClampedArray% Uint8ClampedArray Uint8ClampedArray 构造函数 (23.2)
%Uint16Array% Uint16Array Uint16Array 构造函数 (23.2)
%Uint32Array% Uint32Array Uint32Array 构造函数 (23.2)
%URIError% URIError URIError 构造函数 (20.5.5.6)
%WeakMap% WeakMap WeakMap 构造函数 (24.3.1)
%WeakRef% WeakRef WeakRef 构造函数 (26.1.1)
%WeakSet% WeakSet WeakSet 构造函数 (24.4.1)
注意

表 97 中有额外的条目。

6.2 ECMAScript 规范类型

规范类型对应于在算法中使用的元值,用于描述 ECMAScript 语言结构和 ECMAScript 语言类型 的语义。规范类型包括引用(Reference)、列表(List)完成记录(Completion Record)属性描述符(Property Descriptor)环境记录(Environment Record)抽象闭包(Abstract Closure)数据块(Data Block)。规范类型值是规范的产物,不一定对应于 ECMAScript 实现中的任何特定实体。规范类型值可用于描述 ECMAScript 表达式评估的中间结果,但这些值不能存储为对象的属性或 ECMAScript 语言变量的值。

6.2.1 枚举规范类型

枚举是规范内部的值,不能直接从 ECMAScript 代码中观察到。枚举用 sans-serif 字体表示。例如,完成记录[[Type]] 字段取值如 normalreturnthrow。枚举除了名称外没有其他特征。枚举的名称仅用于区分其他枚举,并不暗示其在上下文中的使用或意义。

6.2.2 列表和记录规范类型

列表类型用于解释参数列表的评估(参见 13.3.8)在 new 表达式、函数调用和其他需要简单有序值列表的算法中。列表类型的值是包含各个值的列表元素的简单有序序列。这些序列可以是任意长度的。列表元素可以使用基于 0 的索引随机访问。为了表示方便,可以使用类似数组的语法来访问列表元素。例如,arguments[2] 是表示列表 arguments 的第 3 个元素的简写。

当算法迭代列表元素而不指定顺序时,使用的顺序是列表中元素的顺序。

为了在本规范中表示方便,可以使用字面量语法来表示新的列表值。例如,« 1, 2 » 定义了一个包含两个元素的列表值,每个元素初始化为特定值。一个新的空列表可以表示为 « »。

在本规范中,短语“列表连接 AB、...”(其中每个参数是一个可能为空的列表)表示一个新列表值,其元素是每个参数(按顺序)的元素(按顺序)的连接。

记录类型用于描述本规范算法中的数据聚合。记录类型值由一个或多个命名字段组成。每个字段的值是一个 ECMAScript 语言值 或规范值。字段名称总是用双括号括起来,例如 [[Value]]

为了在本规范中表示方便,可以使用类似对象字面量的语法来表示记录值。例如,{ [[Field1]]: 42, [[Field2]]: false, [[Field3]]: empty } 定义了一个包含三个字段的记录值,每个字段初始化为特定值。字段名称的顺序不重要。任何未明确列出的字段都被认为是缺席的。

在规范文本和算法中,可以使用点表示法来引用记录值的特定字段。例如,如果 R 是前一段中显示的记录,则 R.[[Field2]] 是“R 中名为 [[Field2]] 的字段”的简写。

常用记录字段组合的模式可以命名,并且该名称可以用作字面量记录值的前缀,以标识所描述的特定聚合类型。例如:PropertyDescriptor { [[Value]]: 42, [[Writable]]: false, [[Configurable]]: true }。

6.2.3 集合和关系规范类型

集合类型用于解释 内存模型 中使用的无序元素集合。它不同于同名的 ECMAScript 集合类型。为了消除歧义,本规范中始终将 ECMAScript 集合实例称为“Set 对象”。集合类型的值是简单元素集合,其中没有元素出现多次。可以向集合中添加和删除元素。集合可以进行并集、交集或差集运算。

关系类型用于解释对集合的约束。关系类型的值是其值域中值的有序对集合。例如,事件上的关系是事件的有序对集合。对于关系 RR 值域中的两个值 aba R b 是表示有序对 (a, b) 是 R 成员的简写。关系在某些条件下是最小的,当它是满足这些条件的最小关系时。

严格偏序是满足以下条件的关系值 R

  • 对于 R 域中的所有 abc

    • 不是 a R a,并且
    • 如果 a R bb R c,则 a R c
注意 1

上述两个属性分别称为非自反性和传递性。

严格全序是满足以下条件的关系值 R

  • 对于 R 域中的所有 abc

    • aba R bb R a,并且
    • 不是 a R a,并且
    • 如果 a R bb R c,则 a R c
注意 2

上述三个属性分别称为完全性、非自反性和传递性。

6.2.4 完成记录规范类型

完成记录规范类型用于解释值和控制流的运行时传播,例如执行非本地控制转移的语句(breakcontinuereturnthrow)的行为。

完成记录具有 表 7 中定义的字段。

表 7: 完成记录 字段
字段名称 含义
[[Type]] normalbreakcontinuereturnthrow 发生的完成类型。
[[Value]] 任何值,除了 完成记录 产生的值。
[[Target]] 字符串或 empty 定向控制转移的目标标签。

以下简短术语有时用于指代完成记录。

  • 正常完成指任何 [[Type]] 值为 normal 的完成记录。
  • 中断完成指任何 [[Type]] 值为 break 的完成记录。
  • 继续完成指任何 [[Type]] 值为 continue 的完成记录。
  • 返回完成指任何 [[Type]] 值为 return 的完成记录。
  • 抛出完成指任何 [[Type]] 值为 throw 的完成记录。
  • 异常完成指任何 [[Type]] 值不是 normal 的完成记录。
  • 某种类型的 正常完成包含[[Value]] 字段中包含该类型值的正常完成。

本规范中定义的可调用对象仅返回正常完成或抛出完成。返回任何其他类型的完成记录被视为编辑错误。

实现定义 的可调用对象必须返回正常完成或抛出完成。

6.2.4.1 NormalCompletion ( value )

抽象操作 NormalCompletion 接受参数 value(任何值,除了 完成记录)并返回一个 正常完成。它在调用时执行以下步骤:

  1. 返回 完成记录 { [[Type]]: normal, [[Value]]: value, [[Target]]: empty }.

6.2.4.2 ThrowCompletion ( value )

抽象操作 ThrowCompletion 接受参数 value(一个 ECMAScript 语言值)并返回一个 抛出完成。它在调用时执行以下步骤:

  1. 返回 完成记录 { [[Type]]: throw, [[Value]]: value, [[Target]]: empty }.

6.2.4.3 UpdateEmpty ( completionRecord, value )

抽象操作 UpdateEmpty 接受参数 completionRecord(一个 完成记录)和 value(任何值,除了 完成记录)并返回一个 完成记录。它在调用时执行以下步骤:

  1. 断言:如果 completionRecord返回完成抛出完成,则 completionRecord.[[Value]] 不是 empty
  2. 如果 completionRecord.[[Value]] 不是 empty,返回 ? completionRecord
  3. 返回 完成记录 { [[Type]]: completionRecord.[[Type]], [[Value]]: value, [[Target]]: completionRecord.[[Target]] }.

6.2.5 引用记录规范类型

引用记录类型用于解释 deletetypeof、赋值运算符、super 关键字 和其他语言特性的行为。例如,赋值运算符的左操作数预期会产生一个引用记录。

引用记录是已解析的名称或属性绑定;其字段由 表 8 定义。

表 8: 引用记录 字段
字段名称 含义
[[Base]] 一个 ECMAScript 语言值、一个 环境记录unresolvable 持有绑定的值或 环境记录[[Base]]unresolvable 表示绑定无法解析。
[[ReferencedName]] 字符串、符号或 私有名称 绑定的名称。如果 [[Base]] 值是 环境记录,则始终为字符串。
[[Strict]] 布尔值 true 如果引用记录源自 严格模式代码false 否则。
[[ThisValue]] 一个 ECMAScript 语言值empty 如果不是 empty,则引用记录表示使用 super 关键字 表达的属性绑定;它被称为 超级引用记录,其 [[Base]] 值永远不会是 环境记录。在这种情况下,[[ThisValue]] 字段保存创建引用记录时的 this 值。

以下 抽象操作 用于在本规范中操作引用记录:

6.2.5.1 IsPropertyReference ( V )

抽象操作 IsPropertyReference 接受参数 V(一个 引用记录)并返回一个布尔值。它在调用时执行以下步骤:

  1. 如果 V.[[Base]]unresolvable,返回 false
  2. 如果 V.[[Base]] 是一个 环境记录,返回 false;否则返回 true

6.2.5.2 IsUnresolvableReference ( V )

抽象操作 IsUnresolvableReference 接受参数 V(一个 引用记录)并返回一个布尔值。当调用时,它执行以下步骤:

  1. 如果 V.[[Base]]unresolvable,返回 true;否则返回 false

6.2.5.3 IsSuperReference ( V )

抽象操作 IsSuperReference 接受参数 V(一个 引用记录)并返回一个布尔值。当调用时,它执行以下步骤:

  1. 如果 V.[[ThisValue]] 不是 empty,返回 true;否则返回 false

6.2.5.4 IsPrivateReference ( V )

抽象操作 IsPrivateReference 接受参数 V(一个 引用记录)并返回一个布尔值。当调用时,它执行以下步骤:

  1. 如果 V.[[ReferencedName]]私有名称,返回 true;否则返回 false

6.2.5.5 GetValue ( V )

抽象操作 GetValue 接受参数 V(一个 引用记录 或一个 ECMAScript 语言值)并返回一个 正常完成包含 一个 ECMAScript 语言值 或一个 突然完成。当调用时,它执行以下步骤:

  1. 如果 V 不是一个 引用记录,返回 V
  2. 如果 IsUnresolvableReference(V) 是 true,抛出一个 ReferenceError 异常。
  3. 如果 IsPropertyReference(V) 是 true,那么
    1. baseObj 为 ? ToObject(V.[[Base]])。
    2. 如果 IsPrivateReference(V) 是 true,那么
      1. 返回 ? PrivateGet(baseObj, V.[[ReferencedName]])。
    3. 返回 ? baseObj.[[Get]](V.[[ReferencedName]], GetThisValue(V))。
  4. 否则,
    1. baseV.[[Base]]
    2. 断言base 是一个 环境记录
    3. 返回 ? base.GetBindingValue(V.[[ReferencedName]], V.[[Strict]])(见 9.1)。
注意

在步骤 3.a 中可能创建的对象在上述抽象操作和 普通对象 [[Get]] 内部方法之外不可访问。实现可能会选择避免实际创建该对象。

6.2.5.6 PutValue ( V, W )

抽象操作 PutValue 接受参数 V(一个 引用记录 或一个 ECMAScript 语言值)和 W(一个 ECMAScript 语言值)并返回一个 正常完成包含 unused 或一个 突然完成。当调用时,它执行以下步骤:

  1. 如果 V 不是一个 引用记录,抛出一个 ReferenceError 异常。
  2. 如果 IsUnresolvableReference(V) 是 true,那么
    1. 如果 V.[[Strict]]true,抛出一个 ReferenceError 异常。
    2. globalObjGetGlobalObject()。
    3. 执行 ? Set(globalObj, V.[[ReferencedName]], W, false)。
    4. 返回 unused
  3. 如果 IsPropertyReference(V) 是 true,那么
    1. baseObj 为 ? ToObject(V.[[Base]])。
    2. 如果 IsPrivateReference(V) 是 true,那么
      1. 返回 ? PrivateSet(baseObj, V.[[ReferencedName]], W)。
    3. succeeded 为 ? baseObj.[[Set]](V.[[ReferencedName]], W, GetThisValue(V))。
    4. 如果 succeededfalseV.[[Strict]]true,抛出一个 TypeError 异常。
    5. 返回 unused
  4. 否则,
    1. baseV.[[Base]]
    2. 断言base 是一个 环境记录
    3. 返回 ? base.SetMutableBinding(V.[[ReferencedName]], W, V.[[Strict]])(见 9.1)。
注意

在步骤 3.a 中可能创建的对象在上述抽象操作和 普通对象 [[Set]] 内部方法之外不可访问。实现可能会选择避免实际创建该对象。

6.2.5.7 GetThisValue ( V )

抽象操作GetThisValue接受参数V(一个引用记录)并返回一个ECMAScript语言值。它在调用时执行以下步骤:

  1. 断言IsPropertyReference(V) 是true
  2. 如果IsSuperReference(V) 是true,返回V.[[ThisValue]];否则返回V.[[Base]]

6.2.5.8 InitializeReferencedBinding ( V, W )

抽象操作InitializeReferencedBinding接受参数V(一个引用记录)和W(一个ECMAScript语言值)并返回一个正常完成包含 未使用或一个突然完成。它在调用时执行以下步骤:

  1. 断言IsUnresolvableReference(V) 是false
  2. baseV.[[Base]]
  3. 断言base是一个环境记录
  4. 返回 ? base.InitializeBinding(V.[[ReferencedName]], W)。

6.2.5.9 MakePrivateReference ( baseValue, privateIdentifier )

抽象操作MakePrivateReference接受参数baseValue(一个ECMAScript语言值)和privateIdentifier(一个字符串)并返回一个引用记录。它在调用时执行以下步骤:

  1. privEnv运行执行上下文的PrivateEnvironment。
  2. 断言privEnv不是null
  3. privateNameResolvePrivateIdentifier(privEnv, privateIdentifier)。
  4. 返回引用记录 { [[Base]]: baseValue, [[ReferencedName]]: privateName, [[Strict]]: true, [[ThisValue]]: empty }。

6.2.6 属性描述符规范类型

属性描述符类型用于解释对象属性属性的操作和具体化。属性描述符是一个记录,包含零个或多个字段,其中每个字段的名称是一个属性名称,其值是对应的属性值,如6.1.7.1中所指定。本规范中用于标记属性描述符记录的架构名称是“PropertyDescriptor”。

属性描述符值可以根据某些字段的存在或使用进一步分类为数据属性描述符和访问器属性描述符。数据属性描述符是包含名为[[Value]][[Writable]]的字段的描述符。访问器属性描述符是包含名为[[Get]][[Set]]的字段的描述符。任何属性描述符都可能包含名为[[Enumerable]][[Configurable]]的字段。属性描述符值不能同时是数据属性描述符和访问器属性描述符;然而,它可以既不是(在这种情况下,它是一个通用属性描述符)。一个完全填充的属性描述符是访问器属性描述符或数据属性描述符,并且具有表3中定义的所有对应字段。

以下抽象操作用于在本规范中操作属性描述符值:

6.2.6.1 IsAccessorDescriptor ( Desc )

抽象操作IsAccessorDescriptor接受参数Desc(一个属性描述符undefined)并返回一个布尔值。它在调用时执行以下步骤:

  1. 如果Descundefined,返回false
  2. 如果Desc[[Get]]字段,返回true
  3. 如果Desc[[Set]]字段,返回true
  4. 返回false

6.2.6.2 IsDataDescriptor ( Desc )

抽象操作IsDataDescriptor接受参数Desc(一个属性描述符undefined)并返回一个布尔值。它在调用时执行以下步骤:

  1. 如果Descundefined,返回false
  2. 如果Desc[[Value]]字段,返回true
  3. 如果Desc[[Writable]]字段,返回true
  4. 返回false

6.2.6.3 IsGenericDescriptor ( Desc )

抽象操作IsGenericDescriptor接受参数Desc(一个属性描述符undefined)并返回一个布尔值。它在调用时执行以下步骤:

  1. 如果Descundefined,返回false
  2. 如果IsAccessorDescriptor(Desc) 是true,返回false
  3. 如果IsDataDescriptor(Desc) 是true,返回false
  4. 返回true

6.2.6.4 FromPropertyDescriptor ( Desc )

抽象操作FromPropertyDescriptor接受参数Desc(一个属性描述符undefined)并返回一个对象或undefined。它在调用时执行以下步骤:

  1. 如果Descundefined,返回undefined
  2. objOrdinaryObjectCreate(%Object.prototype%)。
  3. 断言obj是一个可扩展的普通对象,没有自己的属性。
  4. 如果Desc[[Value]]字段,则
    1. 执行! CreateDataPropertyOrThrow(obj, "value", Desc.[[Value]])。
  5. 如果Desc[[Writable]]字段,则
    1. 执行! CreateDataPropertyOrThrow(obj, "writable", Desc.[[Writable]])。
  6. 如果Desc[[Get]]字段,则
    1. 执行! CreateDataPropertyOrThrow(obj, "get", Desc.[[Get]])。
  7. 如果Desc[[Set]]字段,则
    1. 执行! CreateDataPropertyOrThrow(obj, "set", Desc.[[Set]])。
  8. 如果Desc[[Enumerable]]字段,则
    1. 执行! CreateDataPropertyOrThrow(obj, "enumerable", Desc.[[Enumerable]])。
  9. 如果Desc[[Configurable]]字段,则
    1. 执行! CreateDataPropertyOrThrow(obj, "configurable", Desc.[[Configurable]])。
  10. 返回obj

6.2.6.5 ToPropertyDescriptor ( Obj )

抽象操作ToPropertyDescriptor接受参数Obj(一个ECMAScript语言值)并返回一个正常完成包含一个属性描述符或一个抛出完成。它在调用时执行以下步骤:

  1. 如果Obj不是一个对象,抛出一个TypeError异常。
  2. desc为一个新属性描述符,最初没有字段。
  3. hasEnumerable为? HasProperty(Obj, "enumerable")。
  4. 如果hasEnumerabletrue,则
    1. enumerableToBoolean(? Get(Obj, "enumerable"))。
    2. desc.[[Enumerable]]enumerable
  5. hasConfigurable为? HasProperty(Obj, "configurable")。
  6. 如果hasConfigurabletrue,则
    1. configurableToBoolean(? Get(Obj, "configurable"))。
    2. desc.[[Configurable]]configurable
  7. hasValue为? HasProperty(Obj, "value")。
  8. 如果hasValuetrue,则
    1. value为? Get(Obj, "value")。
    2. desc.[[Value]]value
  9. hasWritable为? HasProperty(Obj, "writable")。
  10. 如果hasWritabletrue,则
    1. writableToBoolean(? Get(Obj, "writable"))。
    2. desc.[[Writable]]writable
  11. hasGet为? HasProperty(Obj, "get")。
  12. 如果hasGettrue,则
    1. getter为? Get(Obj, "get")。
    2. 如果IsCallable(getter)是falsegetter不是undefined,抛出一个TypeError异常。
    3. desc.[[Get]]getter
  13. hasSet为? HasProperty(Obj, "set")。
  14. 如果hasSettrue,则
    1. setter为? Get(Obj, "set")。
    2. 如果IsCallable(setter)是falsesetter不是undefined,抛出一个TypeError异常。
    3. desc.[[Set]]setter
  15. 如果desc[[Get]]字段或desc[[Set]]字段,则
    1. 如果desc[[Value]]字段或desc[[Writable]]字段,抛出一个TypeError异常。
  16. 返回desc

6.2.6.6 CompletePropertyDescriptor ( Desc )

抽象操作CompletePropertyDescriptor接受参数Desc(一个属性描述符)并返回未使用。它在调用时执行以下步骤:

  1. like记录 { [[Value]]: undefined, [[Writable]]: false, [[Get]]: undefined, [[Set]]: undefined, [[Enumerable]]: false, [[Configurable]]: false }。
  2. 如果IsGenericDescriptor(Desc) 是trueIsDataDescriptor(Desc) 是true,则
    1. 如果Desc没有[[Value]]字段,设Desc.[[Value]]like.[[Value]]
    2. 如果Desc没有[[Writable]]字段,设Desc.[[Writable]]like.[[Writable]]
  3. 否则
    1. 如果Desc没有[[Get]]字段,设Desc.[[Get]]like.[[Get]]
    2. 如果Desc没有[[Set]]字段,设Desc.[[Set]]like.[[Set]]
  4. 如果Desc没有[[Enumerable]]字段,设Desc.[[Enumerable]]like.[[Enumerable]]
  5. 如果Desc没有[[Configurable]]字段,设Desc.[[Configurable]]like.[[Configurable]]
  6. 返回未使用

6.2.7 环境记录规范类型

环境记录类型用于解释嵌套函数和块中的名称解析行为。这种类型及其操作在9.1中定义。

6.2.8 抽象闭包规范类型

抽象闭包规范类型用于引用算法步骤以及一组值。抽象闭包通过函数应用风格调用,例如closure(arg1, arg2)。与抽象操作类似,调用抽象闭包时执行其描述的算法步骤。

在创建抽象闭包的算法步骤中,值通过“捕获”动词后跟别名列表来捕获。当创建抽象闭包时,它会捕获创建时与每个别名关联的值。在指定抽象闭包被调用时要执行的算法步骤中,每个捕获的值通过用于捕获该值的别名来引用。

如果抽象闭包返回一个完成记录,该完成记录必须是正常完成抛出完成

抽象闭包作为其他算法的一部分内联创建,如下例所示。

  1. addend为41。
  2. closure为一个新抽象闭包,参数为(x),捕获addend,并在调用时执行以下步骤:
    1. 返回x + addend
  3. valclosure(1)。
  4. 断言val为42。

6.2.9 数据块

数据块规范类型用于描述一个独特且可变的字节大小(8位)数值序列。字节值是一个整数,范围在包含区间从0到255。 数据块值在创建时具有固定数量的字节,每个字节的初始值为0。

为了在本规范中表示方便,可以使用类似数组的语法来访问数据块值的各个字节。这种表示法将数据块值呈现为从0开始的整数索引字节序列。例如,如果db是一个5字节的数据块值,则db[2]可以用来访问其第3个字节。

驻留在可以被多个代理并发引用的内存中的数据块被称为共享数据块。共享数据块具有地址无关的身份(用于测试共享数据块值的相等性):它不绑定到任何进程中块映射到的虚拟地址,而是绑定到块表示的内存位置集合。两个数据块相等仅当它们包含的位置集合相等;否则,它们不相等,并且它们包含的位置集合的交集为空。最后,共享数据块可以与数据块区分开来。

共享数据块的语义通过共享数据块事件内存模型定义。抽象操作引入共享数据块事件,并作为评估语义和内存模型的事件语义之间的接口。事件形成一个候选执行,内存模型在此基础上充当过滤器。请查阅内存模型以获取完整语义。

共享数据块事件记录建模,定义在内存模型中。

以下抽象操作用于在本规范中操作数据块值:

6.2.9.1 CreateByteDataBlock ( size )

抽象操作CreateByteDataBlock接受参数size(一个非负整数)并返回一个正常完成包含一个数据块或一个抛出完成。它在调用时执行以下步骤:

  1. 如果size > 253 - 1,抛出一个RangeError异常。
  2. db为一个新数据块值,包含size字节。如果无法创建这样的数据块,抛出一个RangeError异常。
  3. db的所有字节设置为0。
  4. 返回db

6.2.9.2 CreateSharedByteDataBlock ( size )

抽象操作 CreateSharedByteDataBlock 接受参数 size(一个非负的 整数) 并返回一个 正常完成记录 包含一个 共享数据块 或一个 抛出完成记录。它在被调用时执行以下步骤:

  1. db 为一个由 size 字节组成的新 共享数据块 值。如果无法创建这样的 共享数据块,则抛出一个 RangeError 异常。
  2. execution周围代理代理记录[[CandidateExecution]] 字段。
  3. eventsRecordexecution.[[EventsRecords]]代理事件记录,其 [[AgentSignifier]]代理标识符()。
  4. zero 为 « 0 »。
  5. 对于 db 的每个索引 i,执行以下步骤:
    1. 写共享内存 { [[Order]]: init, [[NoTear]]: true, [[Block]]: db, [[ByteIndex]]: i, [[ElementSize]]: 1, [[Payload]]: zero } 追加到 eventsRecord.[[EventList]]
  6. 返回 db

6.2.9.3 CopyDataBlockBytes ( toBlock, toIndex, fromBlock, fromIndex, count )

抽象操作 CopyDataBlockBytes 接受参数 toBlock(一个 数据块 或一个 共享数据块), toIndex(一个非负的 整数),fromBlock(一个 数据块 或一个 共享数据块),fromIndex(一个非负的 整数),和 count(一个非负的 整数)并返回 unused。它在被调用时执行以下步骤:

  1. 断言fromBlocktoBlock 是不同的值。
  2. fromSizefromBlock 中的字节数。
  3. 断言fromIndex + countfromSize
  4. toSizetoBlock 中的字节数。
  5. 断言toIndex + counttoSize
  6. 重复,当 count > 0 时,执行以下步骤:
    1. 如果 fromBlock 是一个 共享数据块,则
      1. execution周围代理代理记录[[CandidateExecution]] 字段。
      2. eventsRecordexecution.[[EventsRecords]]代理事件记录,其 [[AgentSignifier]]代理标识符()。
      3. bytes 为一个 列表,其唯一元素是一个不确定选择的 字节值
      4. 注意:在实现中,bytes 是底层硬件上非原子读指令的结果。这种不确定性是 内存模型 的语义描述,用于描述具有弱一致性硬件的可观察行为。
      5. readEvent读共享内存 { [[Order]]: unordered, [[NoTear]]: true, [[Block]]: fromBlock, [[ByteIndex]]: fromIndex, [[ElementSize]]: 1 }。
      6. readEvent 追加到 eventsRecord.[[EventList]]
      7. 选择值记录 { [[Event]]: readEvent, [[ChosenValue]]: bytes } 追加到 execution.[[ChosenValues]]
      8. 如果 toBlock 是一个 共享数据块,则
        1. 写共享内存 { [[Order]]: unordered, [[NoTear]]: true, [[Block]]: toBlock, [[ByteIndex]]: toIndex, [[ElementSize]]: 1, [[Payload]]: bytes } 追加到 eventsRecord.[[EventList]]
      9. 否则,
        1. toBlock[toIndex] 设置为 bytes[0]。
    2. 否则,
      1. 断言toBlock 不是一个 共享数据块
      2. toBlock[toIndex] 设置为 fromBlock[fromIndex]。
    3. toIndex 设置为 toIndex + 1。
    4. fromIndex 设置为 fromIndex + 1。
    5. count 设置为 count - 1。
  7. 返回 unused

6.2.10 私有元素规范类型

私有元素类型是一个 记录,用于规范私有类字段、方法和访问器。尽管 属性描述符 不适用于私有元素,但私有字段的行为类似于不可配置、不可枚举、可写的 数据属性,私有方法的行为类似于不可配置、不可枚举、不可写的 数据属性,私有访问器的行为类似于不可配置、不可枚举的 访问器属性

私有元素类型的值是 记录 值,其字段由 表 9 定义。这些值被称为 私有元素

表 9: 私有元素 字段
字段名称 [[Kind]] 字段值 含义
[[Key]] 所有 一个 私有名称 字段、方法或访问器的名称。
[[Kind]] 所有 field, method, 或 accessor 元素的种类。
[[Value]] fieldmethod 一个 ECMAScript 语言值 字段的值。
[[Get]] accessor 一个 函数对象undefined 私有访问器的 getter。
[[Set]] accessor 一个 函数对象undefined 私有访问器的 setter。

6.2.11 类字段定义记录规范类型

类字段定义类型是一个 记录,用于规范类字段。

类字段定义类型的值是 记录 值,其字段由 表 10 定义。这些值被称为 类字段定义记录

表 10: 类字段定义记录 字段
字段名称 含义
[[Name]] 一个 私有名称、字符串或符号 字段的名称。
[[Initializer]] 一个 ECMAScript 函数对象empty 字段的初始化器(如果有)。

6.2.12 私有名称

私有名称规范类型用于描述一个全局唯一的值(不同于任何其他私有名称,即使它们在其他方面无法区分),该值表示私有类元素(字段、方法或访问器)的键。每个私有名称都有一个关联的不可变 [[Description]],它是一个 字符串 值。私有名称可以通过 PrivateFieldAddPrivateMethodOrAccessorAdd 安装在任何 ECMAScript 对象上,然后使用 PrivateGetPrivateSet 进行读取或写入。

6.2.13 类静态块定义记录规范类型

类静态块定义记录是一个 记录 值,用于封装类静态初始化块的可执行代码。

类静态块定义记录的字段列在 表 11 中。

表 11: 类静态块定义记录 字段
字段名称 含义
[[BodyFunction]] 一个 ECMAScript 函数对象 在类静态初始化期间调用的 函数对象

7 抽象操作

这些操作不是 ECMAScript 语言的一部分;它们在这里仅用于帮助规范 ECMAScript 语言的语义。其他更专业的 抽象操作 定义在本规范的其他部分。

7.1 类型转换

ECMAScript 语言在需要时隐式执行自动类型转换。为了阐明某些结构的语义,定义了一组转换 抽象操作。这些转换 抽象操作 是多态的;它们可以接受任何 ECMAScript 语言类型 的值。但其他规范类型不与这些操作一起使用。

ECMAScript 语言中的 BigInt 类型 没有隐式转换;程序员必须显式调用 BigInt 来从其他类型转换值。

7.1.1 ToPrimitive ( input [ , preferredType ] )

抽象操作 ToPrimitive 接受参数 input(一个 ECMAScript 语言值)和可选参数 preferredTypestringnumber)并返回一个 正常完成包含 一个 ECMAScript 语言值 或一个 抛出完成。它将其 input 参数转换为非 对象类型。如果对象能够转换为多种原始类型,它可能会使用可选提示 preferredType 来优先考虑该类型。它在被调用时执行以下步骤:

  1. 如果 input 是一个对象, then
    1. exoticToPrim 为 ? GetMethod(input, @@toPrimitive)。
    2. 如果 exoticToPrim 不是 undefined, then
      1. 如果 preferredType 不存在,则
        1. hint"default"
      2. 否则如果 preferredTypestring,则
        1. hint"string"
      3. 否则,
        1. 断言preferredTypenumber
        2. hint"number"
      4. result 为 ? Call(exoticToPrim, input, « hint »)。
      5. 如果 result 不是一个对象,返回 result
      6. 抛出一个 TypeError 异常。
    3. 如果 preferredType 不存在,令 preferredTypenumber
    4. 返回 ? OrdinaryToPrimitive(input, preferredType)。
  2. 返回 input
注意

当 ToPrimitive 被调用时不带提示时,它的行为通常类似于提示为 number。然而,对象可以通过定义 @@toPrimitive 方法来覆盖这种行为。在本规范中,只有日期对象(参见 21.4.4.45)和符号对象(参见 20.4.3.5)覆盖了默认的 ToPrimitive 行为。日期对象将没有提示视为提示为 string

7.1.1.1 OrdinaryToPrimitive ( O, hint )

抽象操作 OrdinaryToPrimitive 接受参数 O(一个对象)和 hintstringnumber)并返回一个 正常完成包含 一个 ECMAScript 语言值 或一个 抛出完成。它在被调用时执行以下步骤:

  1. 如果 hintstring,则
    1. methodNames 为 « "toString", "valueOf" »。
  2. 否则,
    1. methodNames 为 « "valueOf", "toString" »。
  3. 对于 methodNames 的每个元素 name,执行
    1. method 为 ? Get(O, name)。
    2. 如果 IsCallable(method) is true,则
      1. result 为 ? Call(method, O)。
      2. 如果 result 不是一个对象,返回 result
  4. 抛出一个 TypeError 异常。

7.1.2 ToBoolean ( argument )

抽象操作 ToBoolean 接受参数 argument(一个 ECMAScript 语言值)并返回一个布尔值。它将 argument 转换为布尔类型。 它在被调用时执行以下步骤:

  1. 如果 argument 是一个布尔值,返回 argument
  2. 如果 argument 是以下之一:undefinednull+0𝔽-0𝔽NaN0 或空字符串,返回 false
  3. 注意:这一步在 B.3.6.1 中被替换。
  4. 返回 true

7.1.3 ToNumeric ( value )

抽象操作 ToNumeric 接受参数 value(一个 ECMAScript 语言值)并返回一个 正常完成包含 一个数字或 BigInt,或一个 抛出完成。它返回 value 转换为数字或 BigInt。它在被调用时执行以下步骤:

  1. primValue 为 ? ToPrimitive(value, number)。
  2. 如果 primValue 是一个 BigInt,返回 primValue
  3. 返回 ? ToNumber(primValue)。

7.1.4 ToNumber ( argument )

抽象操作 ToNumber 接受参数 argument(一个 ECMAScript 语言值)并返回一个 正常完成包含 一个数字或一个 抛出完成。它将 argument 转换为数字类型。它在被调用时执行以下步骤:

  1. 如果 argument 是一个数字,返回 argument
  2. 如果 argument 是符号或 BigInt,抛出一个 TypeError 异常。
  3. 如果 argumentundefined,返回 NaN
  4. 如果 argumentnullfalse,返回 +0𝔽
  5. 如果 argumenttrue,返回 1𝔽
  6. 如果 argument 是一个字符串,返回 StringToNumber(argument)。
  7. 断言argument 是一个对象
  8. primValue 为 ? ToPrimitive(argument, number)。
  9. 断言primValue 不是一个对象
  10. 返回 ? ToNumber(primValue)。

7.1.4.1 ToNumber 应用于字符串类型

抽象操作 StringToNumber 指定如何将字符串值转换为数字值,使用以下语法。

语法

StringNumericLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt StrWhiteSpace ::: StrWhiteSpaceChar StrWhiteSpaceopt StrWhiteSpaceChar ::: WhiteSpace LineTerminator StrNumericLiteral ::: StrDecimalLiteral NonDecimalIntegerLiteral[~Sep] StrDecimalLiteral ::: StrUnsignedDecimalLiteral + StrUnsignedDecimalLiteral - StrUnsignedDecimalLiteral StrUnsignedDecimalLiteral ::: Infinity DecimalDigits[~Sep] . DecimalDigits[~Sep]opt ExponentPart[~Sep]opt . DecimalDigits[~Sep] ExponentPart[~Sep]opt DecimalDigits[~Sep] ExponentPart[~Sep]opt

所有未明确定义的语法符号均使用词法语法中为数字字面量定义的定义(12.9.3

注意

应注意字符串数字字面量数字字面量的语法差异:

7.1.4.1.1 StringToNumber ( str )

抽象操作 StringToNumber 接受参数 str(一个字符串)并返回一个数字。 当调用时,它执行以下步骤:

  1. textStringToCodePoints(str).
  2. literalParseText(text, StringNumericLiteral).
  3. 如果 literal 是一个 List 的错误,返回 NaN.
  4. 返回 StringNumericValueliteral.

7.1.4.1.2 运行时语义:StringNumericValue

语法导向操作 StringNumericValue 不接受参数并返回一个数字。

注意

StringNumericLiteral 转换为数字值的整体过程类似于确定 NumericValueNumericLiteral(见 12.9.3),但某些细节有所不同。

它在以下产生式上分段定义:

StringNumericLiteral ::: StrWhiteSpaceopt
  1. 返回 +0𝔽
StringNumericLiteral ::: StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt
  1. 返回 StringNumericValueStrNumericLiteral
StrNumericLiteral ::: NonDecimalIntegerLiteral
  1. 返回 𝔽(MV of NonDecimalIntegerLiteral)。
StrDecimalLiteral ::: - StrUnsignedDecimalLiteral
  1. aStringNumericValueStrUnsignedDecimalLiteral
  2. 如果 a+0𝔽,返回 -0𝔽
  3. 返回 -a
StrUnsignedDecimalLiteral ::: Infinity
  1. 返回 +∞𝔽
StrUnsignedDecimalLiteral ::: DecimalDigits . DecimalDigitsopt ExponentPartopt
  1. a 为第一个 DecimalDigits 的 MV。
  2. 如果第二个 DecimalDigits 存在,则
    1. b 为第二个 DecimalDigits 的 MV。
    2. n 为第二个 DecimalDigits 的代码点数。
  3. 否则,
    1. b 为 0。
    2. n 为 0。
  4. 如果 ExponentPart 存在,令 eExponentPart 的 MV。否则,令 e 为 0。
  5. 返回 RoundMVResult((a + (b × 10-n)) × 10e)。
StrUnsignedDecimalLiteral ::: . DecimalDigits ExponentPartopt
  1. bDecimalDigits 的 MV。
  2. 如果 ExponentPart 存在,令 eExponentPart 的 MV。否则,令 e 为 0。
  3. nDecimalDigits 的代码点数。
  4. 返回 RoundMVResult(b × 10e - n)。
StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPartopt
  1. aDecimalDigits 的 MV。
  2. 如果 ExponentPart 存在,令 eExponentPart 的 MV。否则,令 e 为 0。
  3. 返回 RoundMVResult(a × 10e)。

7.1.4.1.3 RoundMVResult ( n )

抽象操作 RoundMVResult 接受参数 n(一个 mathematical value)并返回一个数字。它以一种实现定义的方式将 n 转换为数字。对于此抽象操作的目的,如果一个数字不是零,或者它的左边和右边都有非零数字,则该数字是重要的。对于此抽象操作的目的,“表示的 mathematical value”是“十进制表示”的逆。它执行以下步骤:

  1. 如果 n 的十进制表示有 20 个或更少的有效数字,返回 𝔽(n)。
  2. option1 为结果的 mathematical value,其中 n 的十进制表示中第 20 位之后的每个有效数字都被替换为 0。
  3. option2 为结果的 mathematical value,其中 n 的十进制表示中第 20 位之后的每个有效数字都被替换为 0,然后在第 20 位处递增(必要时进位)。
  4. chosen实现定义option1option2 的选择。
  5. 返回 𝔽(chosen)。

7.1.5 ToIntegerOrInfinity ( argument )

抽象操作 ToIntegerOrInfinity 接受参数 argument(一个 ECMAScript 语言 值)并返回一个 正常 完成包含 一个 整数、+∞ 或 -∞,或一个 抛出 完成。它将 argument 转换为一个 整数,表示其 数值的小数部分被截断,或者在数值为无穷大时转换为 +∞ 或 -∞。它在调用时执行以下步骤:

  1. number 为 ? ToNumber(argument).
  2. 如果 numberNaN+0𝔽-0𝔽,返回 0.
  3. 如果 number+∞𝔽, 返回 +∞.
  4. 如果 number-∞𝔽, 返回 -∞.
  5. 返回 truncate((number)).
注意
𝔽(ToIntegerOrInfinity(x)) 永远不会返回 -0𝔽 对于任何 x 的值。小数部分的截断 是在将 x 转换为 数学 值 之后进行的。

7.1.6 ToInt32 ( argument )

抽象操作 ToInt32 接受参数 argument(一个 ECMAScript 语言 值)并返回一个 正常 完成包含 一个 整数 Number 或一个 抛出 完成。它将 argument 转换为 232整数 Number 值之一,范围在 包含区间𝔽(-231) 到 𝔽(231 - 1)。它在调用时执行以下步骤:

  1. number 为 ? ToNumber(argument).
  2. 如果 number 不是 有限number+0𝔽-0𝔽, 返回 +0𝔽.
  3. inttruncate((number)).
  4. int32bitint modulo 232.
  5. 如果 int32bit ≥ 231,返回 𝔽(int32bit - 232);否则返回 𝔽(int32bit).
注意

根据上述 ToInt32 的定义:

  • ToInt32 抽象操作是幂等的:如果应用于其产生的结果,第二次应用不会改变该值。
  • ToInt32(ToUint32(x)) 与 ToInt32(x) 对于所有 x 的值是相同的。(为了保持这一特性,+∞𝔽-∞𝔽 被映射到 +0𝔽。)
  • ToInt32 将 -0𝔽 映射到 +0𝔽

7.1.7 ToUint32 ( argument )

抽象操作 ToUint32 接受参数 argument(一个 ECMAScript 语言 值)并返回一个 正常 完成包含 一个 整数 Number 或一个 抛出 完成。它将 argument 转换为 232整数 Number 值之一,范围在 包含区间+0𝔽𝔽(232 - 1)。它在调用时执行以下步骤:

  1. number 为 ? ToNumber(argument).
  2. 如果 number 不是 有限number+0𝔽-0𝔽, 返回 +0𝔽.
  3. inttruncate((number)).
  4. int32bitint modulo 232.
  5. 返回 𝔽(int32bit).
注意

根据上述 ToUint32 的定义:

  • 步骤 5 是 ToUint32 和 ToInt32 之间的唯一区别。
  • ToUint32 抽象操作是幂等的:如果应用于其产生的结果,第二次应用不会改变该值。
  • ToUint32(ToInt32(x)) 与 ToUint32(x) 对于所有 x 的值是相同的。(为了保持这一特性,+∞𝔽-∞𝔽 被映射到 +0𝔽。)
  • ToUint32 将 -0𝔽 映射到 +0𝔽

7.1.8 ToInt16 ( argument )

抽象操作 ToInt16 接受参数 argument(一个 ECMAScript 语言值)并返回一个 正常完成,其中包含一个 整数,或者一个 抛出完成。它将 argument 转换为 216整数值之一,这些值位于 闭区间 𝔽(-215) 到 𝔽(215 - 1) 之间。调用时,它执行以下步骤:

  1. number 为 ? ToNumber(argument)。
  2. 如果 number 不是 有限的 或者 number+0𝔽-0𝔽,返回 +0𝔽
  3. int截断((number))。
  4. int16bitint 216
  5. 如果 int16bit ≥ 215,返回 𝔽(int16bit - 216);否则返回 𝔽(int16bit)。

7.1.9 ToUint16 ( argument )

抽象操作 ToUint16 接受参数 argument(一个 ECMAScript 语言值)并返回一个 正常完成,其中包含一个 整数,或者一个 抛出完成。它将 argument 转换为 216整数值之一,这些值位于 闭区间 +0𝔽𝔽(216 - 1) 之间。调用时,它执行以下步骤:

  1. number 为 ? ToNumber(argument)。
  2. 如果 number 不是 有限的 或者 number+0𝔽-0𝔽,返回 +0𝔽
  3. int截断((number))。
  4. int16bitint 216
  5. 返回 𝔽(int16bit)。
注意

根据上述 ToUint16 的定义:

  • 在第 4 步中将 216 替换为 232 是 ToUint32 和 ToUint16 唯一的区别。
  • ToUint16 将 -0𝔽 映射为 +0𝔽

7.1.10 ToInt8 ( argument )

抽象操作 ToInt8 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成,其中包含一个 整数,或者一个 抛出完成。它将 argument 转换为 28整数值之一,这些值位于 闭区间 -128𝔽127𝔽 之间。调用时,它执行以下步骤:

  1. number 为 ? ToNumber(argument)。
  2. 如果 number 不是 有限的 或者 number+0𝔽-0𝔽,返回 +0𝔽
  3. int截断((number))。
  4. int8bitint 28
  5. 如果 int8bit ≥ 27,返回 𝔽(int8bit - 28);否则返回 𝔽(int8bit)。

7.1.11 ToUint8(argument

抽象操作ToUint8接受参数argument(一个ECMAScript语言值),并返回一个包含整数Number正常完成或一个抛出完成。它将argument转换为从+0𝔽255𝔽的28整数Number值中的一个,这些值在包含区间内。当被调用时,执行以下步骤:

  1. numberToNumber(argument)。
  2. 如果number不是有限的,或number+0𝔽-0𝔽,则返回+0𝔽
  3. int截断((number))。
  4. int8bitint 28
  5. 返回 𝔽(int8bit)。

7.1.12 ToUint8Clamp ( argument )

抽象操作 ToUint8Clamp 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个 整数 或一个 抛出完成记录。它将 argument 钳制和四舍五入到 28整数 值之一,在 闭区间+0𝔽255𝔽 之间。调用时执行以下步骤:

  1. number 为 ? ToNumber(argument)。
  2. 如果 numberNaN,返回 +0𝔽
  3. mvnumber 的扩展数学值
  4. clamped mv 钳制在 0 和 255 之间的结果。
  5. ffloor(clamped)。
  6. 如果 clamped < f + 0.5,返回 𝔽(f)。
  7. 如果 clamped > f + 0.5,返回 𝔽(f + 1)。
  8. 如果 f 是偶数,返回 𝔽(f)。否则,返回 𝔽(f + 1)。
注意

与大多数其他 ECMAScript 整数 转换操作不同,ToUint8Clamp 是四舍五入而不是截断非整数值。它还使用“向偶数舍入”的中点舍入方法,这与 Math.round 的“向上舍入”方法不同。

7.1.13 ToBigInt ( argument )

抽象操作 ToBigInt 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个 BigInt 或一个 抛出完成记录。它将 argument 转换为 BigInt 值,或者在需要从 Number 隐式转换时抛出错误。调用时执行以下步骤:

  1. prim 为 ? ToPrimitive(argument, number)。
  2. 返回 prim表 12 中对应的值。
表 12: BigInt 转换
参数类型 结果
Undefined 抛出 TypeError 异常。
Null 抛出 TypeError 异常。
Boolean 如果 primtrue,返回 1n;如果 primfalse,返回 0n
BigInt 返回 prim
Number 抛出 TypeError 异常。
String
  1. nStringToBigInt(prim)。
  2. 如果 nundefined,抛出 SyntaxError 异常。
  3. 返回 n
Symbol 抛出 TypeError 异常。

7.1.14 StringToBigInt ( str )

抽象操作 StringToBigInt 接受参数 str(一个字符串)并返回一个 BigInt 或 undefined。调用时执行以下步骤:

  1. textStringToCodePoints(str)。
  2. literalParseText(text, StringIntegerLiteral)。
  3. 如果 literal 是一个 错误列表,返回 undefined
  4. mvliteral 的 MV。
  5. 断言mv 是一个 整数
  6. 返回 (mv)。

7.1.14.1 StringIntegerLiteral 语法

StringToBigInt 使用以下语法。

语法

StringIntegerLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrIntegerLiteral StrWhiteSpaceopt StrIntegerLiteral ::: SignedInteger[~Sep] NonDecimalIntegerLiteral[~Sep]

7.1.14.2 运行时语义:MV

7.1.15 ToBigInt64 ( argument )

抽象操作 ToBigInt64 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个 BigInt 或一个 抛出完成记录。它将 argument 转换为 264 个 BigInt 值之一,在 闭区间(-263) 到 (263 - 1)。调用时执行以下步骤:

  1. n 为 ? ToBigInt(argument)。
  2. int64bit(n) 取模 264
  3. 如果 int64bit ≥ 263,返回 (int64bit - 264);否则返回 (int64bit)。

7.1.16 ToBigUint64 ( argument )

抽象操作 ToBigUint64 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个 BigInt 或一个 抛出完成记录。它将 argument 转换为 264 个 BigInt 值之一,在 闭区间0(264 - 1)。调用时执行以下步骤:

  1. n 为 ? ToBigInt(argument)。
  2. int64bit(n) 取模 264
  3. 返回 (int64bit)。

7.1.17 ToString ( argument )

抽象操作 ToString 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个字符串或一个 抛出完成记录。它将 argument 转换为一个字符串类型的值。调用时执行以下步骤:

  1. 如果 argument 是一个字符串,返回 argument
  2. 如果 argument 是一个符号,抛出一个 TypeError 异常。
  3. 如果 argumentundefined,返回 "undefined"
  4. 如果 argumentnull,返回 "null"
  5. 如果 argumenttrue,返回 "true"
  6. 如果 argumentfalse,返回 "false"
  7. 如果 argument 是一个数字,返回 Number::toString(argument, 10)。
  8. 如果 argument 是一个 BigInt,返回 BigInt::toString(argument, 10)。
  9. 断言argument 是一个对象
  10. primValue 为 ? ToPrimitive(argument, string)。
  11. 断言primValue 不是一个对象
  12. 返回 ? ToString(primValue)。

7.1.18 ToObject ( argument )

抽象操作 ToObject 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个对象或一个 抛出完成记录。它根据 表 13argument 转换为对象类型的值:

表 13: ToObject 转换
参数类型 结果
Undefined 抛出一个 TypeError 异常。
Null 抛出一个 TypeError 异常。
Boolean 返回一个新的布尔对象,其 [[BooleanData]] 内部槽被设置为 argument。参见 20.3 获取布尔对象的描述。
Number 返回一个新的数字对象,其 [[NumberData]] 内部槽被设置为 argument。参见 21.1 获取数字对象的描述。
String 返回一个新的字符串对象,其 [[StringData]] 内部槽被设置为 argument。参见 22.1 获取字符串对象的描述。
Symbol 返回一个新的符号对象,其 [[SymbolData]] 内部槽被设置为 argument。参见 20.4 获取符号对象的描述。
BigInt 返回一个新的 BigInt 对象,其 [[BigIntData]] 内部槽被设置为 argument。参见 21.2 获取 BigInt 对象的描述。
Object 返回 argument

7.1.19 ToPropertyKey ( argument )

抽象操作 ToPropertyKey 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个 属性键 或一个 抛出完成记录。它将 argument 转换为可以用作 属性键 的值。调用时执行以下步骤:

  1. key 为 ? ToPrimitive(argument, string)。
  2. 如果 key 是一个符号,那么
    1. 返回 key
  3. 返回 ! ToString(key)。

7.1.20 ToLength ( argument )

抽象操作 ToLength 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个 整数 或一个 抛出完成记录。它将 argument 钳制和截取为一个适合作为 类数组对象 长度的 整数。调用时执行以下步骤:

  1. len 为 ? ToIntegerOrInfinity(argument)。
  2. 如果 len ≤ 0,返回 +0𝔽
  3. 返回 𝔽(min(len, 253 - 1))。

7.1.21 CanonicalNumericIndexString ( argument )

抽象操作 CanonicalNumericIndexString 接受参数 argument(一个字符串)并返回一个数字或 undefined。如果 argument"-0" 或完全匹配某个数字值 nToString(n) 的结果,则返回相应的数字值。否则,它返回 undefined。调用时执行以下步骤:

  1. 如果 argument"-0",返回 -0𝔽
  2. n 为 ! ToNumber(argument)。
  3. 如果 ! ToString(n) 是 argument,返回 n
  4. 返回 undefined

一个规范数字字符串是任何使 CanonicalNumericIndexString 抽象操作不返回 undefined 的字符串值。

7.1.22 ToIndex ( value )

抽象操作 ToIndex 接受参数 value(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个非负 整数 或一个 抛出完成记录。它将 value 转换为一个 整数,并返回该 整数,如果它是非负的并且对应于一个 整数索引。否则,它会抛出一个异常。调用时执行以下步骤:

  1. integer 为 ? ToIntegerOrInfinity(value)。
  2. 如果 integer 不在从 0 到 253 - 1 的 闭区间 内,抛出一个 RangeError 异常。
  3. 返回 integer

7.2 测试和比较操作

7.2.1 RequireObjectCoercible ( argument )

抽象操作 RequireObjectCoercible 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个 ECMAScript 语言值 或一个 抛出完成记录。如果 argument 是一个无法使用 ToObject 转换为对象的值,则抛出一个错误。其定义见 表 14

表 14: RequireObjectCoercible 结果
参数类型 结果
Undefined 抛出一个 TypeError 异常。
Null 抛出一个 TypeError 异常。
Boolean 返回 argument
Number 返回 argument
String 返回 argument
Symbol 返回 argument
BigInt 返回 argument
Object 返回 argument

7.2.2 IsArray ( argument )

抽象操作 IsArray 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个布尔值或一个 抛出完成记录。调用时执行以下步骤:

  1. 如果 argument 不是一个对象,返回 false
  2. 如果 argument 是一个 数组异质对象,返回 true
  3. 如果 argument 是一个 代理异质对象,那么
    1. 执行 ? ValidateNonRevokedProxy(argument)。
    2. proxyTargetargument.[[ProxyTarget]]
    3. 返回 ? IsArray(proxyTarget)。
  4. 返回 false

7.2.3 IsCallable ( argument )

抽象操作 IsCallable 接受参数 argument(一个 ECMAScript 语言值),并返回一个布尔值。它确定 argument 是否是一个具有 [[Call]] 内部方法的可调用函数。调用时执行以下步骤:

  1. 如果 argument 不是一个对象,返回 false
  2. 如果 argument 具有 [[Call]] 内部方法,返回 true
  3. 返回 false

7.2.4 IsConstructor ( argument )

抽象操作 IsConstructor 接受参数 argument(一个 ECMAScript 语言值),并返回一个布尔值。它确定 argument 是否是一个具有 [[Construct]] 内部方法的 函数对象。调用时执行以下步骤:

  1. 如果 argument 不是一个对象,返回 false
  2. 如果 argument 具有 [[Construct]] 内部方法,返回 true
  3. 返回 false

7.2.5 IsExtensible ( O )

抽象操作 IsExtensible 接受参数 O(一个对象),并返回一个 正常完成记录,包含 一个布尔值或一个 抛出完成记录。它用于确定是否可以向 O 添加其他属性。调用时执行以下步骤:

  1. 返回 ? O.[[IsExtensible]]()。

7.2.6 IsIntegralNumber ( argument )

抽象操作 IsIntegralNumber 接受参数 argument(一个 ECMAScript 语言值),并返回一个布尔值。它确定 argument 是否是一个 有限的 整数 值。调用时执行以下步骤:

  1. 如果 argument 不是一个数字,返回 false
  2. 如果 argument 不是 有限的,返回 false
  3. 如果 truncate((argument)) ≠ (argument), 返回 false
  4. 返回 true

7.2.7 IsPropertyKey ( argument )

抽象操作 IsPropertyKey 接受参数 argument(一个 ECMAScript 语言值),并返回一个布尔值。它确定 argument 是否是一个可以用作 属性键 的值。调用时执行以下步骤:

  1. 如果 argument 是一个字符串,返回 true
  2. 如果 argument 是一个符号,返回 true
  3. 返回 false

7.2.8 IsRegExp ( argument )

抽象操作 IsRegExp 接受参数 argument(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含 一个布尔值或一个 抛出完成记录。调用时执行以下步骤:

  1. 如果 argument 不是一个对象,返回 false
  2. matcher 为 ? Get(argument, @@match)。
  3. 如果 matcher 不是 undefined,返回 ToBoolean(matcher)。
  4. 如果 argument 具有 [[RegExpMatcher]] 内部槽,返回 true
  5. 返回 false

7.2.9 静态语义:IsStringWellFormedUnicode ( string )

抽象操作 IsStringWellFormedUnicode 接受参数 string(一个字符串),并返回一个布尔值。它将 string 解释为一系列 UTF-16 编码的代码点,如 6.1.4 中描述,并确定它是否是一个 格式良好 的 UTF-16 序列。调用时执行以下步骤:

  1. lenstring 的长度。
  2. k 为 0。
  3. 重复,直到 k < len
    1. cpCodePointAt(string, k)。
    2. 如果 cp.[[IsUnpairedSurrogate]]true,返回 false
    3. k 设置为 k + cp.[[CodeUnitCount]]
  4. 返回 true

7.2.10 SameValue ( x, y )

抽象操作 SameValue 接受参数 x(一个 ECMAScript 语言值)和 y(一个 ECMAScript 语言值),并返回一个布尔值。它确定这两个参数是否是相同的值。调用时执行以下步骤:

  1. 如果 Type(x) 不是 Type(y),返回 false
  2. 如果 x 是一个数字,那么
    1. 返回 Number::sameValue(x, y)。
  3. 返回 SameValueNonNumber(x, y)。
注意

这个算法不同于 IsStrictlyEqual 算法,因为它将所有 NaN 值视为等价,并区分 +0𝔽-0𝔽

7.2.11 SameValueZero ( x, y )

抽象操作 SameValueZero 接受参数 x(一个 ECMAScript 语言值)和 y(一个 ECMAScript 语言值),并返回一个布尔值。它确定这两个参数是否是相同的值(忽略 +0𝔽-0𝔽 之间的差异)。调用时执行以下步骤:

  1. 如果 Type(x) 不是 Type(y),返回 false
  2. 如果 x 是一个数字,那么
    1. 返回 Number::sameValueZero(x, y)。
  3. 返回 SameValueNonNumber(x, y)。
注意

SameValueZero 与 SameValue 的唯一区别是它将 +0𝔽-0𝔽 视为等价。

7.2.12 SameValueNonNumber ( x, y )

抽象操作 SameValueNonNumber 接受参数 x(一个 ECMAScript 语言值,但不是数字)和 y(一个 ECMAScript 语言值,但不是数字),并返回一个布尔值。调用时执行以下步骤:

  1. 断言Type(x) 是 Type(y)。
  2. 如果 xnullundefined,返回 true
  3. 如果 x 是一个 BigInt,那么
    1. 返回 BigInt::equal(x, y)。
  4. 如果 x 是一个字符串,那么
    1. 如果 xy 具有相同的长度并且在相同的位置具有相同的代码单元,返回 true;否则,返回 false
  5. 如果 x 是一个布尔值,那么
    1. 如果 xy 都是 true 或都为 false,返回 true;否则,返回 false
  6. 注意:所有其他 ECMAScript 语言值 通过身份进行比较。
  7. 如果 xy,返回 true;否则,返回 false
注意 1
出于阐述目的,即使没有必要,也会在此算法中单独处理某些情况。
注意 2
有关“xy”的具体含义详见 5.2.7

7.2.13 IsLessThan ( x, y, LeftFirst )

抽象操作 IsLessThan 接受参数 x(一个 ECMAScript 语言值),y(一个 ECMAScript 语言值),和 LeftFirst(一个布尔值),并返回一个 正常完成包含一个布尔值或 undefined,或一个 抛出完成。它提供了比较 x < y 的语义,返回 truefalse,或 undefined(表示至少一个操作数是 NaN)。LeftFirst 标志用于控制对 xy 进行可能具有可见副作用的操作的顺序。这是必要的,因为 ECMAScript 指定了从左到右的表达式求值顺序。如果 LeftFirsttruex 参数对应于出现在 y 参数对应表达式左侧的表达式。如果 LeftFirstfalse,情况相反,必须在 x 之前对 y 进行操作。它在调用时执行以下步骤:

  1. 如果 LeftFirsttrue,则
    1. px 为 ? ToPrimitive(x, number).
    2. py 为 ? ToPrimitive(y, number).
  2. 否则
    1. 注意:需要反转求值顺序以保持从左到右的求值。
    2. py 为 ? ToPrimitive(y, number).
    3. px 为 ? ToPrimitive(x, number).
  3. 如果 px 是一个 字符串py 是一个 字符串,则
    1. lxpx 的长度。
    2. lypy 的长度。
    3. 对于每个 整数 i 使得 0 ≤ i < min(lx, ly), 按升序进行以下操作
      1. cxpx 中索引 i 处的代码单元数值。
      2. cypy 中索引 i 处的代码单元数值。
      3. 如果 cx < cy,返回 true.
      4. 如果 cx > cy,返回 false.
    4. 如果 lx < ly,返回 true。否则,返回 false.
  4. 否则
    1. 如果 px 是一个 BigIntpy 是一个 字符串,则
      1. nyStringToBigInt(py).
      2. 如果 nyundefined,返回 undefined.
      3. 返回 BigInt::lessThan(px, ny).
    2. 如果 px 是一个 字符串py 是一个 BigInt,则
      1. nxStringToBigInt(px).
      2. 如果 nxundefined,返回 undefined.
      3. 返回 BigInt::lessThan(nx, py).
    3. 注意:因为 pxpy 是原始值,求值顺序不重要。
    4. nx 为 ? ToNumeric(px).
    5. ny 为 ? ToNumeric(py).
    6. 如果 Type(nx) 是 Type(ny),则
      1. 如果 nx 是一个 数字,则
        1. 返回 Number::lessThan(nx, ny).
      2. 否则
        1. 断言nx 是一个 BigInt.
        2. 返回 BigInt::lessThan(nx, ny).
    7. 断言nx 是一个 BigIntny 是一个 数字,或 nx 是一个 数字ny 是一个 BigInt.
    8. 如果 nxnyNaN, 返回 undefined.
    9. 如果 nx-∞𝔽ny+∞𝔽,返回 true.
    10. 如果 nx+∞𝔽ny-∞𝔽,返回 false.
    11. 如果 (nx) < (ny),返回 true;否则返回 false.
注释 1

步骤 3 与算法中处理加法运算符 + 的步骤 1.c 不同 (13.15.3),使用逻辑与操作而不是逻辑或操作。

注释 2

字符串的比较使用简单的按 UTF-16 代码单元值序列的字典顺序,没有尝试使用 Unicode 规范中定义的更复杂的、语义导向的字符或字符串相等性和排序顺序定义。因此,根据 Unicode 标准正规等价但不在相同规范化形式中的字符串值可能会被测试为不等。同样需要注意的是,对于包含 代理对 的字符串,按代码单元的字典顺序与按代码点的字典顺序不同。

7.2.14 IsLooselyEqual ( x, y )

抽象操作 IsLooselyEqual 接受参数 x(一个 ECMAScript 语言 值)和 y(一个 ECMAScript 语言 值),并返回一个 正常 完成包含 布尔值或一个 抛出 完成。它提供了 == 操作符的语义。它在被调用时执行以下步骤:

  1. 如果 类型(x) 和 类型(y) 相同,则
    1. 返回 严格相等(x, y)。
  2. 如果 xnullyundefined,返回 true
  3. 如果 xundefinedynull,返回 true
  4. 注意:这一步在章节 B.3.6.2 中被替换。
  5. 如果 x 是数字y 是字符串,返回 ! 宽松相等(x, ! 转换为数字(y))。
  6. 如果 x 是字符串y 是数字,返回 ! 宽松相等(! 转换为数字(x), y)。
  7. 如果 x 是 BigInty 是字符串,则
    1. n字符串转换为 BigInt(y)。
    2. 如果 nundefined,返回 false
    3. 返回 ! 宽松相等(x, n)。
  8. 如果 x 是字符串y 是 BigInt,返回 ! 宽松相等(y, x)。
  9. 如果 x 是布尔值,返回 ! 宽松相等(! 转换为数字(x), y)。
  10. 如果 y 是布尔值,返回 ! 宽松相等(x, ! 转换为数字(y))。
  11. 如果 x 是字符串、数字、BigInt 或 Symbol 且 y 是对象,返回 ! 宽松相等(x, ? 转换为原始值(y))。
  12. 如果 x 是对象y 是字符串、数字、BigInt 或 Symbol,返回 ! 宽松相等(? 转换为原始值(x), y)。
  13. 如果 x 是 BigInty 是数字,或如果 x 是数字y 是 BigInt,则
    1. 如果 x 不是 有限y 不是 有限,返回 false
    2. 如果 (x) = (y), 返回 true;否则返回 false
  14. 返回 false

7.2.15 IsStrictlyEqual ( x, y )

抽象操作 IsStrictlyEqual 接受参数 x(一个 ECMAScript 语言值)和 y(一个 ECMAScript 语言值)并返回一个布尔值。它提供了 === 操作符的语义。调用时执行以下步骤:

  1. 如果 Type(x) 不是 Type(y),返回 false
  2. 如果 x 是一个数字,则
    1. 返回 Number::equal(x, y)。
  3. 返回 SameValueNonNumber(x, y)。
注意

该算法在处理有符号零和 NaN 时与 SameValue 算法不同。

7.3 对象操作

7.3.1 MakeBasicObject ( internalSlotsList )

抽象操作 MakeBasicObject 接受参数 internalSlotsList(一个List,包含内部插槽名称),并返回一个对象。它是所有以算法方式创建的 ECMAScript 对象的源头,包括普通对象和异态对象。它因此提取出了创建所有对象时使用的公共步骤,并集中了对象的创建过程。在调用时执行以下步骤:

  1. obj 成为一个新创建的对象,其内部包含 internalSlotsList 中每个名称的内部插槽。
  2. obj 的关键内部方法设置为默认的普通对象定义,详见10.1
  3. Assert:如果调用者不会覆盖 obj[[GetPrototypeOf]][[SetPrototypeOf]] 关键内部方法中的任意一个,则 internalSlotsList 包含 [[Prototype]]
  4. Assert:如果调用者不会覆盖 obj[[SetPrototypeOf]][[IsExtensible]][[PreventExtensions]] 关键内部方法中的所有一个或多个,则 internalSlotsList 包含 [[Extensible]]
  5. 如果 internalSlotsList 包含 [[Extensible]],则将 obj.[[Extensible]] 设置为 true
  6. 返回 obj
注意

在本规范中,异态对象通过首先调用 MakeBasicObject 来获取基本的基础对象,然后覆盖该对象的一些或全部内部方法,例如ArrayCreateBoundFunctionCreate等抽象操作中创建。为了封装异态对象的创建过程,对象的关键内部方法在这些操作外部永不修改。

7.3.2 Get ( O, P )

抽象操作 Get 接受参数 O(一个对象)和 P(一个属性键),并返回一个正常完成记录,其中包含ECMAScript 语言值抛出完成记录。用于检索对象的特定属性的值。调用时执行以下步骤:

  1. 返回 ? O.[[Get]](P, O).

7.3.3 GetV ( V, P )

抽象操作 GetV 接受参数 V(一个ECMAScript 语言值)和 P(一个属性键),并返回一个正常完成记录,其中包含ECMAScript 语言值抛出完成记录。用于检索ECMAScript 语言值的特定属性的值。如果该值不是对象,则使用适合该值类型的包装对象进行属性查找。调用时执行以下步骤:

  1. O 成为 ? ToObject(V).
  2. 返回 ? O.[[Get]](P, V).

7.3.4 Set ( O, P, V, Throw )

抽象操作 Set 接受参数 O(一个对象)、P(一个属性键)、V(一个ECMAScript 语言值)和 Throw(一个布尔值),并返回一个正常完成记录,其中包含抛出完成记录V是要设置的属性的新值。调用时执行以下步骤:

  1. success 成为 ? O.[[Set]](P, V, O).
  2. 如果 successfalse 并且 Throwtrue,则抛出一个 TypeError 异常。
  3. 返回 unused.

7.3.5 CreateDataProperty ( O, P, V )

抽象操作 CreateDataProperty 接受参数 O(一个对象)、P(一个属性键)和 V(一个ECMAScript 语言值),并返回一个正常完成记录,其中包含抛出完成记录。用于创建对象的新自有属性。调用时执行以下步骤:

  1. newDesc 成为属性描述符 { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }.
  2. 返回 ? O.[[DefineOwnProperty]](P, newDesc).
注意

此抽象操作创建一个属性,其属性设置为 ECMAScript 语言赋值运算符创建的默认值。通常,该属性不会已存在。如果存在且不可配置,或者 O 不可扩展,则 [[DefineOwnProperty]] 将返回 false

7.3.6 CreateDataPropertyOrThrow ( O, P, V )

抽象操作 CreateDataPropertyOrThrow 接受参数 O(一个对象)、P(一个属性键)和 V(一个ECMAScript 语言值),并返回一个正常完成记录,其中包含抛出完成记录 unused。用于创建对象的新自有属性。如果无法执行请求的属性更新,则抛出 TypeError 异常。调用时执行以下步骤:

  1. success 成为 ? CreateDataProperty(O, P, V).
  2. 如果 successfalse,则抛出一个 TypeError 异常。
  3. 返回 unused.
注意

此抽象操作创建一个属性,其属性设置为 ECMAScript 语言赋值运算符创建的默认值。通常,该属性不会已存在。如果存在且不可配置,或者 O 不可扩展,则 [[DefineOwnProperty]] 将返回 false,导致此操作抛出 TypeError 异常。

7.3.7 CreateNonEnumerableDataPropertyOrThrow ( O, P, V )

抽象操作 CreateNonEnumerableDataPropertyOrThrow 接受参数 O(一个对象)、P(一个属性键)和 V(一个ECMAScript 语言值),并返回 unused。用于创建普通对象的新非可枚举自有属性。调用时执行以下步骤:

  1. Assert: O 是一个普通的、可扩展的对象,并且没有不可配置的属性。
  2. newDesc 成为属性描述符 { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
  3. 执行 ! DefinePropertyOrThrow(O, P, newDesc).
  4. 返回 unused.
注意

此抽象操作创建一个属性,其属性设置为与 ECMAScript 语言赋值运算符创建的默认值相同,但不可枚举。通常情况下,该属性不存在。如果存在,则 DefinePropertyOrThrow 保证正常完成。

7.3.8 DefinePropertyOrThrow ( O, P, desc )

抽象操作 DefinePropertyOrThrow 接受参数 O(一个对象)、P(一个属性键)和 desc(一个属性描述符)并返回 normal completion containing unused 或一个 throw completion。用于以可能引发 TypeError 异常的方式调用对象的 [[DefineOwnProperty]] 内部方法,如果无法执行所请求的属性更新。调用时执行以下步骤:

  1. success 成为 ? O.[[DefineOwnProperty]](P, desc).
  2. 如果 successfalse,则抛出 TypeError 异常。
  3. 返回 unused.

7.3.9 DeletePropertyOrThrow ( O, P )

抽象操作 DeletePropertyOrThrow 接受参数 O(一个对象)和 P(一个属性键)并返回 normal completion containing unused 或一个 throw completion。用于移除对象的特定自有属性。如果属性不可配置,则抛出异常。调用时执行以下步骤:

  1. success 成为 ? O.[[Delete]](P).
  2. 如果 successfalse,则抛出 TypeError 异常。
  3. 返回 unused.

7.3.10 GetMethod ( V, P )

抽象操作 GetMethod 接受参数 V(一个ECMAScript 语言值) 和 P(一个属性键)并返回一个normal completion containing包含函数对象undefined,或一个throw completion。用于在期望属性值为函数时获取ECMAScript 语言值的特定属性值。调用时执行以下步骤:

  1. func 成为 ? GetV(V, P).
  2. 如果 funcundefinednull,则返回 undefined
  3. 如果 IsCallable(func) 是 false,则抛出 TypeError 异常。
  4. 返回 func

7.3.11 HasProperty ( O, P )

抽象操作 HasProperty 接受参数 O(一个 Object)和 P(一个 属性键)并返回一个 normal completion containing 一个 Boolean 或一个 throw completion。它用于确定对象是否具有指定的 属性键,该属性可以是自有的或继承的。调用时执行以下步骤:

  1. 返回 ? O.[[HasProperty]](P)。

7.3.12 HasOwnProperty ( O, P )

抽象操作 HasOwnProperty 接受参数 O(一个 Object)和 P(一个 属性键)并返回一个 normal completion containing 一个 Boolean 或一个 throw completion。它用于确定对象是否具有指定的自有 属性键。调用时执行以下步骤:

  1. Let desc be ? O.[[GetOwnProperty]](P).
  2. If desc is undefined, return false.
  3. Return true.

7.3.13 Call ( F, V [ , argumentsList ] )

抽象操作 Call 接受参数 F(一个 ECMAScript 语言值)和 V(一个 ECMAScript 语言值)以及可选参数 argumentsList(一个 List,包含 ECMAScript 语言值)并返回一个 normal completion containing 一个 ECMAScript 语言值 或一个 throw completion。它用于调用 函数对象[[Call]] 内部方法。 F函数对象V[[Call]]this 值,argumentsList 是传递给内部方法的对应参数。如果 argumentsList 不存在,则使用一个新的空 List 作为其值。调用时执行以下步骤:

  1. 如果argumentsList不存在,则将argumentsList设为一个新的空List
  2. 如果IsCallable(F)的返回值为false,则抛出TypeError异常。
  3. 返回 ? F.[[Call]](V, argumentsList)。

7.3.14 构造(F [ , argumentsList [ , newTarget ] ])

抽象操作构造(Construct)接受参数F(一个构造函数)和可选参数argumentsList(一个List,包含ECMAScript语言值)以及newTarget(一个构造函数),并返回一个包含对象的正常完成或抛出异常的抛出完成。它用于调用函数对象[[Construct]]内部方法。参数argumentsListnewTarget将作为相应内部方法的参数传递。如果argumentsList不存在,则使用一个新的空List作为其值。如果newTarget不存在,则使用F作为其值。调用时执行以下步骤:

  1. 如果newTarget不存在,则将newTarget设为F
  2. 如果argumentsList不存在,则将argumentsList设为一个新的空List
  3. 返回 ? F.[[Construct]](argumentsList, newTarget)。

如果newTarget不存在,则该操作等效于:new F(...argumentsList)

7.3.15 SetIntegrityLevel ( O, level )

抽象操作 SetIntegrityLevel 接受参数 O(一个对象)和 levelsealedfrozen),并返回一个包含布尔值的 正常完成或抛出异常的 抛出完成。它用于固定对象的自有属性集合。调用时执行以下步骤:

  1. status 为 ? O.[[PreventExtensions]]()。
  2. 如果 statusfalse,则返回 false
  3. keys 为 ? O.[[OwnPropertyKeys]]()。
  4. 如果 levelsealed,则
    1. 对于 keys 的每个元素 k,执行
      1. 执行 ? DefinePropertyOrThrow(O, k, PropertyDescriptor { [[Configurable]]: false  })。
  5. 否则,
    1. Assertlevelfrozen
    2. 对于 keys 的每个元素 k,执行
      1. currentDesc 为 ? O.[[GetOwnProperty]](k)。
      2. 如果 currentDesc 不是 undefined,则
        1. 如果 IsAccessorDescriptor(currentDesc) 是 true,则
          1. desc 为 PropertyDescriptor { [[Configurable]]: false  }。
        2. 否则,
          1. desc 为 PropertyDescriptor { [[Configurable]]: false, [[Writable]]: false  }。
        3. 执行 ? DefinePropertyOrThrow(O, k, desc)。
  6. 返回 true

7.3.16 TestIntegrityLevel ( O, level )

抽象操作 TestIntegrityLevel 接受参数 O(一个对象)和 levelsealedfrozen),并返回一个包含布尔值的 正常完成或抛出异常的 抛出完成。它用于确定对象的自有属性集合是否被固定。调用时执行以下步骤:

  1. extensible 为 ? IsExtensible(O)。
  2. 如果 extensibletrue,则返回 false
  3. 注意:如果对象是可扩展的,则不检查其任何属性。
  4. keys 为 ? O.[[OwnPropertyKeys]]()。
  5. 对于 keys 的每个元素 k,执行
    1. currentDesc 为 ? O.[[GetOwnProperty]](k)。
    2. 如果 currentDesc 不是 undefined,则
      1. 如果 currentDesc.[[Configurable]]true,则返回 false
      2. 如果 levelfrozen 并且 IsDataDescriptor(currentDesc) 是 true,则
        1. 如果 currentDesc.[[Writable]]true,则返回 false
  6. 返回 true

7.3.17 CreateArrayFromList ( elements )

抽象操作 CreateArrayFromList 接受参数 elements(一个 List,包含 ECMAScript 语言值)并返回一个数组。它用于创建一个数组,其元素由 elements 提供。调用时执行以下步骤:

  1. array 为 ! ArrayCreate(0)。
  2. n 为 0。
  3. 对于 elements 的每个元素 e,执行
    1. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(n)), e)。
    2. n 设为 n + 1。
  4. 返回 array

7.3.18 LengthOfArrayLike ( obj )

抽象操作 LengthOfArrayLike 接受参数 obj(一个对象)并返回一个正常完成,包含非负整数整数或一个抛出完成。它返回类似数组对象的"length"属性值。调用时执行以下步骤:

  1. 返回 (? ToLength(? Get(obj, "length")))。

类似数组对象是指该操作返回正常完成的任何对象。

注意 1
通常,类似数组对象还会具有一些以整数索引命名的属性。但这不是此定义的要求。
注意 2
数组和字符串对象是类似数组对象的示例。

7.3.19 CreateListFromArrayLike ( obj [ , elementTypes ] )

抽象操作 CreateListFromArrayLike 接受参数 obj(一个ECMAScript 语言值)和可选参数 elementTypes(一个List,包含 ECMAScript 语言类型的名称),返回正常完成,包含一个List值,其元素由obj的索引属性提供。 elementTypes 包含创建的List的元素值允许的 ECMAScript 语言类型名称。调用时执行以下步骤:

  1. 如果 elementTypes 不存在,则将 elementTypes 设置为« Undefined, Null, Boolean, String, Symbol, Number, BigInt, Object »。
  2. 如果 obj 不是对象,则抛出 TypeError 异常。
  3. len 是 ? LengthOfArrayLike(obj)。
  4. list 是一个新的空List
  5. index 是 0。
  6. 重复,当 index < len 时,
    1. indexName 是 ! ToString(𝔽(index))。
    2. next 是 ? Get(obj, indexName)。
    3. 如果 elementTypes 不包含 Type(next),则抛出 TypeError 异常。
    4. next 追加到 list
    5. index 设置为 index + 1。
  7. 返回 list

7.3.20 Invoke ( V, P [ , argumentsList ] )

抽象操作 Invoke 接受参数 V(一个ECMAScript 语言值)和 P(一个属性键),可选参数 argumentsList(一个List,包含ECMAScript 语言值),返回正常完成,包含一个ECMAScript 语言值或者抛出完成。该操作用于调用ECMAScript 语言值的方法属性。 V 既用作属性查找点也用作调用的this值。 argumentsList 是传递给方法的参数值列表。如果 argumentsList 不存在,则使用一个新的空List作为其值。调用时执行以下步骤:

  1. 如果 argumentsList 不存在,则将 argumentsList 设置为一个新的空List
  2. func 是 ? GetV(V, P)。
  3. 返回 ? Call(func, V, argumentsList)。

7.3.21 OrdinaryHasInstance ( C, O )

抽象操作 OrdinaryHasInstance 接受参数 C(一个ECMAScript 语言值)和 O(一个ECMAScript 语言值),返回正常完成,包含一个布尔值或者抛出完成。它实现了确定O是否从C提供的实例对象继承路径的默认算法。调用时执行以下步骤:

  1. 如果 IsCallable(C) 为 false,返回 false
  2. 如果 C 有一个 [[BoundTargetFunction]] 内部插槽,则
    1. BCC.[[BoundTargetFunction]]
    2. 返回 ? InstanceofOperator(O, BC)。
  3. 如果 O 不是一个对象,返回 false
  4. P 为 ? Get(C, "prototype")。
  5. 如果 P 不是一个对象,抛出一个 TypeError 异常。
  6. 重复,
    1. O 设置为 ? O.[[GetPrototypeOf]]()。
    2. 如果 Onull,返回 false
    3. 如果 SameValue(P, O) 是 true,返回 true

7.3.22 SpeciesConstructor ( O, defaultConstructor )

抽象操作 SpeciesConstructor 接受参数 O(一个对象)和 defaultConstructor(一个构造函数),返回正常完成,包含一个构造函数或者一个抛出完成。它用于获取应该用于创建从 O 派生的新对象的构造函数。如果无法从 O 开始找到一个构造函数@@species属性,则使用 defaultConstructor。调用时执行以下步骤:

  1. C 为 ? Get(O, "constructor")。
  2. 如果 Cundefined,返回 defaultConstructor
  3. 如果 C 不是一个对象,抛出一个 TypeError 异常。
  4. S 为 ? Get(C, @@species)。
  5. 如果 Sundefined 或者 null,返回 defaultConstructor
  6. 如果 IsConstructor(S) 是 true,返回 S
  7. 抛出一个 TypeError 异常。

7.3.23 EnumerableOwnProperties ( O, kind )

抽象操作 EnumerableOwnProperties 接受参数 O(一个对象)和 kindkeyvaluekey+value),返回 一个正常完成,包含 一个列表ECMAScript 语言值或者一个抛出完成。调用时执行以下步骤:

  1. ownKeys 为 ? O.[[OwnPropertyKeys]]()。
  2. results 为一个新的空列表
  3. 对于 ownKeys 的每个元素 key,做如下操作:
    1. 如果 key字符串,那么:
      1. desc 为 ? O.[[GetOwnProperty]](key)。
      2. 如果 desc 不是 undefined 并且 desc.[[Enumerable]]true,那么:
        1. 如果 kindkey,那么
          1. key 添加到 results 中。
        2. 否则,
          1. value 为 ? Get(O, key)。
          2. 如果 kindvalue,那么:
            1. value 添加到 results 中。
          3. 否则,
            1. 断言kindkey+value
            2. entryCreateArrayFromListkey, value »)。
            3. entry 添加到 results 中。
  4. 返回 results

7.3.24 GetFunctionRealm ( obj )

抽象操作 GetFunctionRealm 接受参数 obj(一个函数对象),返回一个正常完成,包含一个域记录或者一个抛出完成。调用时执行以下步骤:

  1. 如果 obj 拥有一个 [[Realm]] 内部插槽,则:
    1. 返回 obj.[[Realm]]
  2. 如果 obj 是一个绑定函数的外来对象,则:
    1. boundTargetFunctionobj.[[BoundTargetFunction]]
    2. 返回 ? GetFunctionRealm(boundTargetFunction)。
  3. 如果 obj 是一个代理的外来对象,则:
    1. 执行 ? ValidateNonRevokedProxy(obj)。
    2. proxyTargetobj.[[ProxyTarget]]
    3. 返回 ? GetFunctionRealm(proxyTarget)。
  4. 返回 当前域记录
注意

如果 obj 是一个非标准函数外来对象且没有 [[Realm]] 内部插槽,则步骤 4 会被执行。

7.3.25 CopyDataProperties ( target, source, excludedItems )

抽象操作 CopyDataProperties 接受参数 target(一个对象),source (一个ECMAScript 语言值)和 excludedItems(一个列表,包含属性键),并返回一个正常完成,包含 unused或者一个抛出完成。调用时执行以下步骤:

  1. 如果 sourceundefinednull,则返回 unused
  2. from 为 ! ToObject(source)。
  3. keys 为 ? from.[[OwnPropertyKeys]]()。
  4. 对于 keys 中的每个元素 nextKey,执行以下步骤:
    1. excludedfalse
    2. 对于 excludedItems 中的每个元素 e,执行以下步骤:
      1. 如果 SameValue(e, nextKey) 是 true,则执行以下步骤:
        1. excluded 设为 true
    3. 如果 excludedfalse,则执行以下步骤:
      1. desc 为 ? from.[[GetOwnProperty]](nextKey)。
      2. 如果 desc 不是 undefined 并且 desc.[[Enumerable]]true,则执行以下步骤:
        1. propValue 为 ? Get(from, nextKey)。
        2. 执行 ! CreateDataPropertyOrThrow(target, nextKey, propValue)。
  5. 返回 unused
注意

这里传入的目标对象始终是一个新创建的对象,在发生错误抛出时不会直接访问到它。

7.3.26 PrivateElementFind ( O, P )

抽象操作 PrivateElementFind 接受参数 O(一个对象)和 P(一个私有名称),并返回一个PrivateElement或者empty。调用时执行以下步骤:

  1. 如果 O.[[PrivateElements]] 包含一个PrivateElement pe, 使得 pe.[[Key]]P,则执行以下步骤:
    1. 返回 pe
  2. 返回 empty

7.3.27 PrivateFieldAdd ( O, P, value )

抽象操作 PrivateFieldAdd 接受参数 O(一个对象),P(一个私有名称),和 value(一个ECMAScript 语言值),并返回一个normal completion containing unused 或者一个throw completion。调用时执行以下步骤:

  1. If the host is a web browser, then
    1. 执行 ? HostEnsureCanAddPrivateElement(O).
  2. Let entry be PrivateElementFind(O, P).
  3. If entry is not empty, throw a TypeError exception.
  4. Append PrivateElement { [[Key]]: P, [[Kind]]: field, [[Value]]: value } to O.[[PrivateElements]].
  5. Return unused.

7.3.28 PrivateMethodOrAccessorAdd ( O, method )

抽象操作 PrivateMethodOrAccessorAdd 接受参数 O(一个对象)和 method(一个 PrivateElement),并返回一个包含正常完成的 未使用 或抛出完成。调用时执行以下步骤:

  1. Assert: method.[[Kind]]methodaccessor
  2. 如果 主机环境 是 Web 浏览器,则执行:
    1. 执行 ? HostEnsureCanAddPrivateElement(O)。
  3. entry 成为 PrivateElementFind(O, method.[[Key]])。
  4. 如果 entry 不是 empty,则抛出一个 TypeError 异常。
  5. method 添加到 O.[[PrivateElements]]
  6. 返回 unused

私有方法和访问器的值在实例之间是共享的。此操作不会创建方法或访问器的新副本。

7.3.29 HostEnsureCanAddPrivateElement ( O )

主机定义的抽象操作 HostEnsureCanAddPrivateElement 接受参数 O(一个对象),并返回一个包含正常完成的 未使用 或抛出完成。它允许主机环境阻止将私有元素添加到特定的主机定义的外来对象。

HostEnsureCanAddPrivateElement 的实现必须符合以下要求:

  • 如果 O 不是主机定义的外来对象,则此抽象操作必须返回 NormalCompletion(unused),并且不执行其他步骤。
  • 使用相同参数调用此抽象操作的任何两次必须返回相同类型的 完成记录

HostEnsureCanAddPrivateElement 的默认实现是返回 NormalCompletion(unused)。

此抽象操作仅由 ECMAScript 主机,即 Web 浏览器调用。

7.3.30 PrivateGet ( O, P )

抽象操作 PrivateGet 接受参数 O(一个对象)和 P(一个私有名称),并返回一个包含 ECMAScript 语言值的普通完成或抛出完成。调用时执行以下步骤:

  1. entryPrivateElementFind(O, P)。
  2. 如果 entry 为空,则抛出 TypeError 异常。
  3. 如果 entry.[[Kind]]fieldmethod,则
    1. 返回 entry.[[Value]]
  4. Assert:确保 entry.[[Kind]]accessor
  5. 如果 entry.[[Get]]undefined,则抛出 TypeError 异常。
  6. getterentry.[[Get]]
  7. 返回 ? Call(getter, O)。

7.3.31 PrivateSet ( O, P, value )

抽象操作 PrivateSet 接受参数 O(一个对象)、P(一个私有名称)和 value(一个 ECMAScript 语言值),并返回一个包含未使用的普通完成或抛出完成。调用时执行以下步骤:

  1. entryPrivateElementFind(O, P)。
  2. 如果 entry 为空,则抛出 TypeError 异常。
  3. 如果 entry.[[Kind]]field,则
    1. entry.[[Value]] 设置为 value
  4. 否则,如果 entry.[[Kind]]method,则
    1. 抛出 TypeError 异常。
  5. 否则,
    1. Assert: 确保 entry.[[Kind]]accessor
    2. 如果 entry.[[Set]]undefined,则抛出 TypeError 异常。
    3. setterentry.[[Set]]
    4. 执行 ? Call(setter, O, « value »)。
  6. 返回 unused

7.3.32 DefineField ( receiver, fieldRecord )

抽象操作 DefineField 接受参数 receiver(一个对象)和 fieldRecord(一个 ClassFieldDefinition Record),并返回一个包含未使用的普通完成或抛出完成。调用时执行以下步骤:

  1. fieldNamefieldRecord.[[Name]]
  2. initializerfieldRecord.[[Initializer]]
  3. 如果 initializer 不为空,则
    1. initValue 为 ? Call(initializer, receiver)。
  4. 否则,
    1. initValueundefined
  5. 如果 fieldName 是一个 Private Name,则
    1. 执行 ? PrivateFieldAdd(receiver, fieldName, initValue)。
  6. 否则,
    1. Assert: 确保 IsPropertyKey(fieldName) 是 true
    2. 执行 ? CreateDataPropertyOrThrow(receiver, fieldName, initValue)。
  7. 返回 unused

7.3.33 InitializeInstanceElements ( O, constructor )

抽象操作 InitializeInstanceElements 接受参数 O(一个对象)和 constructor(一个 ECMAScript function object),并返回一个包含未使用的普通完成或抛出完成。调用时执行以下步骤:

  1. methodsconstructor.[[PrivateMethods]] 的值。
  2. 对于每个 PrivateElement methodmethods 中,执行
    1. 执行 ? PrivateMethodOrAccessorAdd(O, method)。
  3. fieldsconstructor.[[Fields]] 的值。
  4. 对于每个元素 fieldRecordfields 中,执行
    1. 执行 ? DefineField(O, fieldRecord)。
  5. 返回 unused

7.3.34 AddValueToKeyedGroup ( groups, key, value )

抽象操作 AddValueToKeyedGroup 接受参数 groups(一个包含字段 [[Key]](一个 ECMAScript 语言值)和 [[Elements]](一个 ECMAScript 语言值列表)的 List 的记录),key(一个 ECMAScript 语言值)和 value(一个 ECMAScript 语言值),并返回 unused。调用时执行以下步骤:

  1. 对于每个 记录 { [[Key]], [[Elements]] } ggroups 中,执行
    1. 如果 SameValue(g.[[Key]], key) 的结果为 true,则
      1. Assert: 正好有一个 groups 的元素符合此条件。
      2. value 追加到 g.[[Elements]] 中。
      3. 返回 unused
  2. group 为记录 { [[Key]]: key, [[Elements]]: « value » }。
  3. group 追加到 groups 中。
  4. 返回 unused

7.3.35 GroupBy ( items, callbackfn, keyCoercion )

抽象操作 GroupBy 接受参数 items(一个 ECMAScript 语言值)、callbackfn(一个 ECMAScript 语言值)和 keyCoercionpropertyzero),并返回一个包含字段 [[Key]](一个 ECMAScript 语言值)和 [[Elements]](一个 ECMAScript 语言值列表)的 List 的记录或一个 throw completion。调用时执行以下步骤:

  1. 执行 ? RequireObjectCoercible(items).
  2. 如果 IsCallable(callbackfn) 的结果为 false,则抛出一个 TypeError 异常。
  3. groups 为一个新的空 List
  4. iteratorRecord 为 ? GetIterator(items, sync).
  5. k 为 0。
  6. 重复执行
    1. 如果 k ≥ 253 - 1,则
      1. errorThrowCompletion(一个新创建的 TypeError 对象)。
      2. 返回 ? IteratorClose(iteratorRecord, error).
    2. next 为 ? IteratorStepValue(iteratorRecord).
    3. 如果 nextdone,则
      1. 返回 groups
    4. valuenext
    5. keyCompletion(Call(callbackfn, undefined, « value, 𝔽(k) »)).
    6. IfAbruptCloseIterator(key, iteratorRecord).
    7. 如果 keyCoercionproperty,则
      1. key 设置为 Completion(ToPropertyKey(key)).
      2. IfAbruptCloseIterator(key, iteratorRecord).
    8. 否则,
      1. Assert: keyCoercionzero
      2. 如果 key-0𝔽,则将 key 设置为 +0𝔽
    9. 执行 AddValueToKeyedGroup(groups, key, value).
    10. k 设置为 k + 1。

7.4 迭代器对象操作

请参阅通用迭代接口(27.1)。

7.4.1 迭代器记录

迭代器记录是用于封装迭代器或异步迭代器及其 next 方法的 记录 值。

迭代器记录具有以下在 表格 15 中列出的字段。

表格 15: 迭代器记录 字段
字段名 含义
[[Iterator]] 一个对象 符合 IteratorAsyncIterator 接口的对象。
[[NextMethod]] 一个 ECMAScript 语言值 [[Iterator]] 对象的 next 方法。
[[Done]] 一个布尔值 表示迭代器是否已关闭。

7.4.2 GetIteratorFromMethod ( obj, method )

抽象操作 GetIteratorFromMethod 接受参数 obj(一个 ECMAScript 语言值) 和 method(一个 函数对象),并返回一个包含正常完成或抛出完成的 迭代器记录。 当调用时,执行以下步骤:

  1. iterator be ? Call(method, obj).
  2. If iterator 不是一个对象,抛出一个 TypeError 异常。
  3. nextMethod be ? Get(iterator, "next").
  4. iteratorRecord迭代器记录 { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }。
  5. 返回 iteratorRecord

7.4.3 GetIterator ( obj, kind )

抽象操作 GetIterator 接受参数 obj(一个 ECMAScript 语言值)和 kindsyncasync),并返回一个包含正常完成状态的迭代器记录或抛出异常完成状态。调用时执行以下步骤:

  1. 如果 kindasync,则
    1. method 为 ? GetMethod(obj, @@asyncIterator)。
    2. 如果 methodundefined,则
      1. syncMethod 为 ? GetMethod(obj, @@iterator)。
      2. 如果 syncMethodundefined,则抛出 TypeError 异常。
      3. syncIteratorRecord 为 ? GetIteratorFromMethod(obj, syncMethod)。
      4. 返回 CreateAsyncFromSyncIterator(syncIteratorRecord)。
  2. 否则,
    1. method 为 ? GetMethod(obj, @@iterator)。
  3. 如果 methodundefined,则抛出 TypeError 异常。
  4. 返回 ? GetIteratorFromMethod(obj, method)。

7.4.4 IteratorNext ( iteratorRecord [ , value ] )

抽象操作 IteratorNext 接受参数 iteratorRecord(一个 Iterator Record)和可选参数 value(一个 ECMAScript 语言值),并返回一个包含正常完成状态的对象或抛出异常完成状态。调用时执行以下步骤:

  1. 如果 value 不存在,则
    1. result 为 ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]])。
  2. 否则,
    1. result 为 ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « value »)。
  3. 如果 result 不是对象,则抛出 TypeError 异常。
  4. 返回 result

7.4.5 IteratorComplete ( iterResult )

抽象操作 IteratorComplete 接受参数 iterResult(一个对象)并返回一个包含正常完成状态的布尔值或抛出异常完成状态。调用时执行以下步骤:

  1. 返回 ToBoolean(? Get(iterResult, "done"))。

7.4.6 IteratorValue ( iterResult )

抽象操作 IteratorValue 接受参数 iterResult(一个对象)并返回一个包含正常完成状态的 ECMAScript 语言值或抛出异常完成状态。调用时执行以下步骤:

  1. 返回 ? Get(iterResult, "value")。

7.4.7 IteratorStep ( iteratorRecord )

抽象操作 IteratorStep 接受参数 iteratorRecord(一个 迭代器记录),并返回一个正常完成包含对象或 false,或者抛出完成。它通过调用 iteratorRecord.[[NextMethod]]iteratorRecord.[[Iterator]] 请求下一个值,并根据情况返回 false 表示迭代器已经结束,或者返回可用的 IteratorResult 对象。调用时执行以下步骤:

  1. result 为 ? IteratorNext(iteratorRecord).
  2. done 为 ? IteratorComplete(result).
  3. 如果 donetrue,则返回 false
  4. 返回 result

7.4.8 IteratorStepValue ( iteratorRecord )

抽象操作 IteratorStepValue 接受参数 iteratorRecord(一个 迭代器记录),并返回一个正常完成包含 ECMAScript 语言值或 done,或者抛出完成。它通过调用 iteratorRecord.[[NextMethod]]iteratorRecord.[[Iterator]] 请求下一个值,并根据情况返回 done 表示迭代器已经结束,或者返回从 IteratorResult 对象中获取的值。调用时执行以下步骤:

  1. resultCompletion(IteratorNext(iteratorRecord)).
  2. If result is a throw completion, 则
    1. iteratorRecord.[[Done]] 设置为 true
    2. 返回 ? result
  3. result 设置为 ! result
  4. doneCompletion(IteratorComplete(result)).
  5. If done 是一个 throw completion, 则
    1. iteratorRecord.[[Done]] 设置为 true
    2. 返回 ? done
  6. done 设置为 ! done
  7. If donetrue, 则
    1. iteratorRecord.[[Done]] 设置为 true
    2. 返回 done
  8. valueCompletion(Get(result, "value")).
  9. If value 是一个 throw completion, 则
    1. iteratorRecord.[[Done]] 设置为 true
  10. 返回 ? value

7.4.9 IteratorClose ( iteratorRecord, completion )

抽象操作 IteratorClose 接受参数 iteratorRecord(一个 迭代器记录)和 completion(一个 完成记录),并返回一个 完成记录。它用于通知迭代器在达到完成状态时执行其通常执行的任何操作。调用时执行以下步骤:

  1. AssertiteratorRecord.[[Iterator]] 是一个对象
  2. iteratoriteratorRecord.[[Iterator]]
  3. innerResultCompletion(GetMethod(iterator, "return")).
  4. 如果 innerResult 是一个 正常完成,则
    1. returninnerResult.[[Value]]
    2. 如果 returnundefined,则返回 ? completion
    3. innerResult 设置为 Completion(Call(return, iterator)).
  5. 如果 completion 是一个 抛出完成,则返回 ? completion
  6. 如果 innerResult 是一个 抛出完成,则返回 ? innerResult
  7. 如果 innerResult.[[Value]] 不是一个对象,则抛出 TypeError 异常。
  8. 返回 ? completion

7.4.10 IfAbruptCloseIterator ( value, iteratorRecord )

IfAbruptCloseIterator 是一个使用 迭代器记录 的一系列算法步骤的简写形式。形式为:

  1. IfAbruptCloseIterator(value, iteratorRecord).

意味着与以下内容相同:

  1. Assert: value 是一个 完成记录
  2. 如果 value 是一个 突然完成,则返回 ? IteratorClose(iteratorRecord, value)。
  3. 否则,将 value 设置为 ! value

7.4.11 AsyncIteratorClose ( iteratorRecord, completion )

异步抽象操作 AsyncIteratorClose 接受参数 iteratorRecord (一个 迭代器记录)和 completion (一个 完成记录),并返回一个 完成记录。 用于通知异步迭代器,在达到完成状态时执行其通常执行的任何操作。调用时执行以下步骤:

  1. Assert: iteratorRecord.[[Iterator]] 是一个对象
  2. iteratoriteratorRecord.[[Iterator]]
  3. innerResultCompletion(GetMethod(iterator, "return"))。
  4. 如果 innerResult 是一个 正常完成,则:
    1. returninnerResult.[[Value]]
    2. 如果 returnundefined,返回 ? completion
    3. innerResult 设为 Completion(Call(return, iterator))。
    4. 如果 innerResult 是一个 正常完成, 将 innerResult 设为 Completion(Await(innerResult.[[Value]]))。
  5. 如果 completion 是一个 抛出完成,返回 ? completion
  6. 如果 innerResult 是一个 抛出完成,返回 ? innerResult
  7. 如果 innerResult.[[Value]] 不是一个对象, 抛出 TypeError 异常。
  8. 返回 ? completion

7.4.12 CreateIterResultObject ( value, done )

抽象操作 CreateIterResultObject 接受参数 value (一个 ECMAScript 语言值)和 done (一个布尔值),并返回符合 IteratorResult 接口的对象。它在调用时执行以下步骤:

  1. objOrdinaryObjectCreate(%Object.prototype%)。
  2. 执行 ! CreateDataPropertyOrThrow(obj, "value", value)。
  3. 执行 ! CreateDataPropertyOrThrow(obj, "done", done)。
  4. 返回 obj

7.4.13 CreateListIteratorRecord ( list )

抽象操作 CreateListIteratorRecord 接受参数 list (一个 List,包含 ECMAScript 语言值),并返回一个 Iterator Record。它创建一个迭代器对象记录,其 next 方法返回 list 的连续元素。在调用时执行以下步骤:

  1. closure 成为一个没有参数的新 Abstract Closure,它捕获 list,并在调用时执行以下步骤:
    1. 对于 list 的每个元素 E,执行
      1. 执行 ? GeneratorYield(CreateIterResultObject(E, false))。
    2. 返回 NormalCompletion(undefined)。
  2. iterator 成为 CreateIteratorFromClosure(closure, empty, %IteratorPrototype%)。
  3. 返回 Iterator Record { [[Iterator]]: iterator, [[NextMethod]]: %GeneratorFunction.prototype.prototype.next%, [[Done]]: false }。

列表迭代器对象对 ECMAScript 代码不可直接访问。

7.4.14 IteratorToList ( iteratorRecord )

抽象操作 IteratorToList 接受参数 iteratorRecord (一个 Iterator Record)并返回一个包含 正常完成,其包含 List,或者一个 抛出完成。在调用时执行以下步骤:

  1. values 成为一个新的空 List
  2. 重复执行,
    1. next 成为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,那么
      1. 返回 values
    3. next 追加到 values

8 语法导向操作

除了本节中定义的操作外,专门的语法导向操作在本规范的各个地方进行了定义。

8.1 运行时语义:评估

语法导向操作 Evaluation 不接受参数并返回一个完成记录

注意
该操作的定义分布在本规范的“ECMAScript 语言”部分。每个定义都出现在相关产生式的定义后面。

8.2 Scope 分析

8.2.1 静态语义:BoundNames

语法指导操作 BoundNames 不接受参数,并返回一个字符串列表(List)。

"*default*" 在本规范中用作模块默认导出的合成名称,当没有其他名称时使用。模块的 [[Environment]] 中创建一个以该名称命名的条目,并保存相应的值。通过调用 ResolveExport(exportName [ , resolveSet ]) 解析名为 "default" 的导出,模块会返回一个 ResolvedBinding Record,其 [[BindingName]]"*default*",然后在模块的 [[Environment]] 中解析为上述值。这仅用于规范的便利性,使得匿名默认导出能够像其他任何导出一样解析。这个 "*default*" 字符串对 ECMAScript 代码或模块链接算法是不可访问的。

它在以下产生式上分段定义:

BindingIdentifier : Identifier
  1. 返回一个 List,其唯一元素是 Identifier 的字符串值,来自于 Identifier
BindingIdentifier : yield
  1. 返回 « "yield" »。
BindingIdentifier : await
  1. 返回 « "await" »。
LexicalDeclaration : LetOrConst BindingList ;
  1. 返回 BoundNames 的结果, 来自于 BindingList
BindingList : BindingList , LexicalBinding
  1. names1BoundNames 的结果, 来自于 BindingList
  2. names2BoundNames 的结果, 来自于 LexicalBinding
  3. 返回 list-concatenation 的结果, 包括 names1names2
LexicalBinding : BindingIdentifier Initializeropt
  1. 返回 BoundNames 的结果, 来自于 BindingIdentifier
LexicalBinding : BindingPattern Initializer
  1. 返回 BoundNames 的结果, 来自于 BindingPattern
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. names1BoundNames 的结果, 来自于 VariableDeclarationList
  2. names2BoundNames 的结果, 来自于 VariableDeclaration
  3. 返回 list-concatenation 的结果, 包括 names1names2
VariableDeclaration : BindingIdentifier Initializeropt
  1. 返回 BoundNames 的结果, 来自于 BindingIdentifier
VariableDeclaration : BindingPattern Initializer
  1. 返回 BoundNames 的结果, 来自于 BindingPattern
ObjectBindingPattern : { }
  1. 返回一个新的空 List
ObjectBindingPattern : { BindingPropertyList , BindingRestProperty }
  1. names1 成为 BoundNames 的结果, 其中 BindingPropertyList 是指向的非终结符。
  2. names2 成为 BoundNames 的结果, 其中 BindingRestProperty 是指向的非终结符。
  3. 返回 list-concatenation 的结果, 其中包含 names1names2
ArrayBindingPattern : [ Elisionopt ]
  1. 返回一个新的空 List
ArrayBindingPattern : [ Elisionopt BindingRestElement ]
  1. names 成为 BoundNames 的结果, 其中 BindingRestElement 是指向的非终结符。
ArrayBindingPattern : [ BindingElementList , Elisionopt ]
  1. names1 成为 BoundNames 的结果, 其中 BindingElementList 是指向的非终结符。
  2. names2 成为 BoundNames 的结果, 其中 BindingRestElement 是指向的非终结符。
  3. 返回 list-concatenation 的结果, 其中包含 names1names2
BindingPropertyList : BindingPropertyList , BindingProperty
  1. names1 成为 BoundNames 的结果, 其中 BindingPropertyList 是指向的非终结符。
  2. names2 成为 BoundNames 的结果, 其中 BindingProperty 是指向的非终结符。
  3. 返回 list-concatenation 的结果, 其中包含 names1names2
BindingElementList : BindingElementList , BindingElisionElement
  1. names1 成为 BoundNames 的结果, 其中 BindingElementList 是指向的非终结符。
  2. names2 成为 BoundNames 的结果, 其中 BindingElisionElement 是指向的非终结符。
  3. 返回 list-concatenation 的结果, 其中包含 names1names2
BindingElisionElement : Elisionopt BindingElement
  1. 返回 BoundNames 的结果, 其中 BindingElement 是指向的非终结符。
BindingProperty : PropertyName : BindingElement
  1. 返回 BoundNames 的结果, 其中 BindingElement 是指向的非终结符。
SingleNameBinding : BindingIdentifier Initializeropt
  1. 返回 BoundNames 的结果, 其中 BindingIdentifier 是指向的非终结符。
BindingElement : BindingPattern Initializeropt
  1. 返回 BoundNames 的结果, 其中 BindingPattern 是指向的非终结符。
ForDeclaration : LetOrConst ForBinding
  1. 返回 BoundNames 的结果, 其中 ForBinding 是指向的非终结符。
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. 返回 BoundNames 的结果, 其中 BindingIdentifier 是指向的非终结符。
FunctionDeclaration : function ( FormalParameters ) { FunctionBody }
  1. 返回« "*default*" »。
FormalParameters : [empty]
  1. 返回一个新的空List
FormalParameters : FormalParameterList , FunctionRestParameter
  1. names1 设置为获取 FormalParameterListBoundNames
  2. names2 设置为获取 FunctionRestParameterBoundNames
  3. 返回 list-concatenation 的结果,即 names1names2 的连接列表。
FormalParameterList : FormalParameterList , FormalParameter
  1. names1 设置为获取 FormalParameterListBoundNames
  2. names2 设置为获取 FormalParameterBoundNames
  3. 返回 list-concatenation 的结果,即 names1names2 的连接列表。
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formals 设置为由 ArrowFormalParameters 覆盖的CoverParenthesizedExpressionAndArrowParameterList
  2. 返回 formalsBoundNames
GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody }
  1. 返回BindingIdentifier的绑定名称。
GeneratorDeclaration : function * ( FormalParameters ) { GeneratorBody }
  1. 返回"*default*"
AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }
  1. 返回BindingIdentifierBoundNames
AsyncGeneratorDeclaration : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. 返回 « "*default*" »。
ClassDeclaration : class BindingIdentifier ClassTail
  1. 返回BoundNames中的BindingIdentifier
ClassDeclaration : class ClassTail
  1. 返回 « "*default*" »。
AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }
  1. 返回BoundNames中的BindingIdentifier
AsyncFunctionDeclaration : async function ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 « "*default*" »。
CoverCallExpressionAndAsyncArrowHead : MemberExpression Arguments
  1. head为被CoverCallExpressionAndAsyncArrowHead覆盖的AsyncArrowHead
  2. 返回headBoundNames
ImportDeclaration : import ImportClause FromClause ;
  1. 返回BoundNamesImportClause
ImportDeclaration : import ModuleSpecifier ;
  1. 返回一个新的空List
ImportClause : ImportedDefaultBinding , NameSpaceImport
  1. names1BoundNamesImportedDefaultBindingBoundNames
  2. names2BoundNamesNameSpaceImportBoundNames
  3. 返回list-concatenationnames1names2
ImportClause : ImportedDefaultBinding , NamedImports
  1. names1BoundNamesImportedDefaultBindingBoundNames
  2. names2BoundNamesNamedImportsBoundNames
  3. 返回list-concatenationnames1names2
NamedImports : { }
  1. 返回一个新的空List
ImportsList : ImportsList , ImportSpecifier
  1. names1BoundNamesImportsListBoundNames
  2. names2BoundNamesImportSpecifierBoundNames
  3. 返回list-concatenationnames1names2
ImportSpecifier ModuleExportName as ImportedBinding
  1. 返回ImportedBindingBoundNames
ExportDeclaration export ExportFromClause FromClause export NamedExports
  1. 返回一个新的空List
ExportDeclaration export VariableStatement
  1. 返回VariableStatementBoundNames
ExportDeclaration export Declaration
  1. 返回DeclarationBoundNames
ExportDeclaration export default HoistableDeclaration
  1. declarationNamesHoistableDeclarationBoundNames
  2. 如果declarationNames不包含元素"*default*",则将"*default*"添加到declarationNames中。
  3. 返回declarationNames
ExportDeclaration export default ClassDeclaration
  1. declarationNamesClassDeclarationBoundNames
  2. 如果declarationNames不包含元素"*default*",则将"*default*"添加到declarationNames中。
  3. 返回declarationNames
ExportDeclaration export default AssignmentExpression
  1. 返回« "*default*" »。

8.2.2 静态语义:DeclarationPart

DeclarationPart 是一个语法指导操作,不接受参数并返回一个解析节点(Parse Node)。它根据以下产生式逐段定义:

HoistableDeclaration FunctionDeclaration
  1. 返回 FunctionDeclaration
HoistableDeclaration GeneratorDeclaration
  1. 返回 GeneratorDeclaration
HoistableDeclaration AsyncFunctionDeclaration
  1. 返回 AsyncFunctionDeclaration
HoistableDeclaration AsyncGeneratorDeclaration
  1. 返回 AsyncGeneratorDeclaration
Declaration ClassDeclaration
  1. 返回 ClassDeclaration
Declaration LexicalDeclaration
  1. 返回 LexicalDeclaration

8.2.3 静态语义:IsConstantDeclaration

语法导向操作 IsConstantDeclaration 不接受任何参数,并返回一个布尔值。它在以下产生式上逐段定义:

LexicalDeclaration : LetOrConst BindingList ;
  1. 返回 IsConstantDeclarationLetOrConst
LetOrConst : let
  1. 返回 false
LetOrConst : const
  1. 返回 true
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 false
ClassDeclaration : class BindingIdentifier ClassTail class ClassTail
  1. 返回 false
ExportDeclaration : export ExportFromClause FromClause ; export NamedExports ; export default AssignmentExpression ;
  1. 返回 false
注意

没有必要将 export default AssignmentExpression 视为常量声明,因为没有语法允许对用于引用模块默认对象的内部绑定名称进行赋值。

8.2.4 静态语义:词法声明的名称

语法导向操作 LexicallyDeclaredNames 不接受任何参数,并返回一个字符串列表。它在以下产生式上逐段定义:

Block : { }
  1. 返回一个新的空列表
StatementList : StatementList StatementListItem
  1. names1LexicallyDeclaredNamesStatementList
  2. names2LexicallyDeclaredNamesStatementListItem
  3. 返回 names1names2列表连接
StatementListItem : Statement
  1. 如果 Statement Statement : LabelledStatement ,返回 LexicallyDeclaredNamesLabelledStatement
  2. 返回一个新的空列表
StatementListItem : Declaration
  1. 返回 BoundNamesDeclaration
CaseBlock : { }
  1. 返回一个新的空列表
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 如果第一个CaseClauses存在,令names1为第一个CaseClausesLexicallyDeclaredNames
  2. 否则,令names1为一个新的空列表
  3. names2DefaultClauseLexicallyDeclaredNames
  4. 如果第二个CaseClauses存在,令names3为第二个CaseClausesLexicallyDeclaredNames
  5. 否则,令names3为一个新的空列表
  6. 返回names1names2names3列表连接
CaseClauses : CaseClauses CaseClause
  1. names1LexicallyDeclaredNamesCaseClauses
  2. names2LexicallyDeclaredNamesCaseClause
  3. 返回 names1names2列表连接
CaseClause : case Expression : StatementListopt
  1. 如果StatementList存在,返回StatementListLexicallyDeclaredNames
  2. 返回一个新的空列表
DefaultClause : default : StatementListopt
  1. 如果StatementList存在,返回StatementListLexicallyDeclaredNames
  2. 返回一个新的空列表
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回LexicallyDeclaredNamesLabelledItem
LabelledItem : Statement
  1. 返回一个新的空列表
LabelledItem : FunctionDeclaration
  1. 返回BoundNamesFunctionDeclaration
FunctionStatementList : [empty]
  1. 返回一个新的空列表
FunctionStatementList : StatementList
  1. 返回TopLevelLexicallyDeclaredNamesStatementList
ClassStaticBlockStatementList : [empty]
  1. 返回一个新的空列表
ClassStaticBlockStatementList : StatementList
  1. 返回TopLevelLexicallyDeclaredNamesStatementList
ConciseBody : ExpressionBody
  1. 返回一个新的空列表
AsyncConciseBody : ExpressionBody
  1. 返回一个新的空列表
Script : [empty]
  1. 返回一个新的空列表
ScriptBody : StatementList
  1. 返回TopLevelLexicallyDeclaredNamesStatementList
注意 1

Script的顶层,函数声明被视为var声明,而不是词法声明。

注意 2

Module的LexicallyDeclaredNames包括所有导入绑定的名称。

ModuleItemList : ModuleItemList ModuleItem
  1. names1LexicallyDeclaredNamesModuleItemList
  2. names2LexicallyDeclaredNamesModuleItem
  3. 返回 names1names2列表连接
ModuleItem : ImportDeclaration
  1. 返回BoundNamesImportDeclaration
ModuleItem : ExportDeclaration
  1. 如果ExportDeclarationexport VariableStatement,返回一个新的空列表
  2. 返回BoundNamesExportDeclaration
ModuleItem : StatementListItem
  1. 返回LexicallyDeclaredNamesStatementListItem
注意 3

Module的顶层,函数声明被视为词法声明,而不是var声明。

8.2.5 静态语义:词法作用域声明

语法导向操作 LexicallyScopedDeclarations 不接受任何参数,并返回一个列表,其中包含解析节点。它在以下产生式上逐段定义:

StatementList : StatementList StatementListItem
  1. declarations1LexicallyScopedDeclarationsStatementList
  2. declarations2LexicallyScopedDeclarationsStatementListItem
  3. 返回 declarations1declarations2列表连接
StatementListItem : Statement
  1. 如果Statement Statement : LabelledStatement ,返回LexicallyScopedDeclarationsLabelledStatement
  2. 返回一个新的空列表
StatementListItem : Declaration
  1. 返回一个列表,其唯一元素是DeclarationPartDeclaration
CaseBlock : { }
  1. 返回一个新的空列表
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 如果第一个CaseClauses存在,令declarations1为第一个CaseClausesLexicallyScopedDeclarations
  2. 否则,令declarations1为一个新的空列表
  3. declarations2DefaultClauseLexicallyScopedDeclarations
  4. 如果第二个CaseClauses存在,令declarations3为第二个CaseClausesLexicallyScopedDeclarations
  5. 否则,令declarations3为一个新的空列表
  6. 返回declarations1declarations2declarations3列表连接
CaseClauses : CaseClauses CaseClause
  1. declarations1LexicallyScopedDeclarationsCaseClauses
  2. declarations2LexicallyScopedDeclarationsCaseClause
  3. 返回 declarations1declarations2列表连接
CaseClause : case Expression : StatementListopt
  1. 如果StatementList存在,返回StatementListLexicallyScopedDeclarations
  2. 返回一个新的空列表
DefaultClause : default : StatementListopt
  1. 如果StatementList存在,返回StatementListLexicallyScopedDeclarations
  2. 返回一个新的空列表
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回LexicallyScopedDeclarationsLabelledItem
LabelledItem : Statement
  1. 返回一个新的空列表
LabelledItem : FunctionDeclaration
  1. 返回 « FunctionDeclaration »。
FunctionStatementList : [empty]
  1. 返回一个新的空列表
FunctionStatementList : StatementList
  1. 返回TopLevelLexicallyScopedDeclarationsStatementList
ClassStaticBlockStatementList : [empty]
  1. 返回一个新的空列表
ClassStaticBlockStatementList : StatementList
  1. 返回TopLevelLexicallyScopedDeclarationsStatementList
ConciseBody : ExpressionBody
  1. 返回一个新的空列表
AsyncConciseBody : ExpressionBody
  1. 返回一个新的空列表
Script : [empty]
  1. 返回一个新的空列表
ScriptBody : StatementList
  1. 返回TopLevelLexicallyScopedDeclarationsStatementList
Module : [empty]
  1. 返回一个新的空列表
ModuleItemList : ModuleItemList ModuleItem
  1. declarations1LexicallyScopedDeclarationsModuleItemList
  2. declarations2LexicallyScopedDeclarationsModuleItem
  3. 返回 declarations1declarations2列表连接
ModuleItem : ImportDeclaration
  1. 返回一个新的空列表
ExportDeclaration : export ExportFromClause FromClause ; export NamedExports ; export VariableStatement
  1. 返回一个新的空列表
ExportDeclaration : export Declaration
  1. 返回一个列表,其唯一元素是DeclarationPartDeclaration
ExportDeclaration : export default HoistableDeclaration
  1. 返回一个列表,其唯一元素是DeclarationPartHoistableDeclaration
ExportDeclaration : export default ClassDeclaration
  1. 返回一个列表,其唯一元素是ClassDeclaration
ExportDeclaration : export default AssignmentExpression ;
  1. 返回一个列表,其唯一元素是此ExportDeclaration

8.2.6 静态语义: VarDeclaredNames

语法导向操作 VarDeclaredNames 不接受任何参数,并返回一个字符串列表。它在以下产生式上逐段定义:

Statement : EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement
  1. 返回一个新的空列表
Block : { }
  1. 返回一个新的空列表
StatementList : StatementList StatementListItem
  1. names1VarDeclaredNamesStatementList
  2. names2VarDeclaredNamesStatementListItem
  3. 返回 names1names2列表连接
StatementListItem : Declaration
  1. 返回一个新的空列表
VariableStatement : var VariableDeclarationList ;
  1. 返回BoundNamesVariableDeclarationList
IfStatement : if ( Expression ) Statement else Statement
  1. names1 为第一个VarDeclaredNamesStatement
  2. names2 为第二个VarDeclaredNamesStatement
  3. 返回 names1names2列表连接
IfStatement : if ( Expression ) Statement
  1. 返回VarDeclaredNamesStatement
DoWhileStatement : do Statement while ( Expression ) ;
  1. 返回VarDeclaredNamesStatement
WhileStatement : while ( Expression ) Statement
  1. 返回VarDeclaredNamesStatement
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. 返回VarDeclaredNamesStatement
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. names1BoundNamesVariableDeclarationList
  2. names2VarDeclaredNamesStatement
  3. 返回 names1names2列表连接
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. 返回VarDeclaredNamesStatement
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. 返回VarDeclaredNamesStatement
ForInOfStatement : for ( var ForBinding in Expression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement
  1. names1BoundNamesForBinding
  2. names2VarDeclaredNamesStatement
  3. 返回 names1names2列表连接
注意

本节由附录B.3.5进行扩展。

WithStatement : with ( Expression ) Statement
  1. 返回VarDeclaredNamesStatement
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回VarDeclaredNamesCaseBlock
CaseBlock : { }
  1. 返回一个新的空列表
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 如果第一个CaseClauses存在,令names1为第一个CaseClausesVarDeclaredNames
  2. 否则,令names1为一个新的空列表
  3. names2DefaultClauseVarDeclaredNames
  4. 如果第二个CaseClauses存在,令names3为第二个CaseClausesVarDeclaredNames
  5. 否则,令names3为一个新的空列表
  6. 返回names1names2names3列表连接
CaseClauses : CaseClauses CaseClause
  1. names1VarDeclaredNamesCaseClauses
  2. names2VarDeclaredNamesCaseClause
  3. 返回 names1names2列表连接
CaseClause : case Expression : StatementListopt
  1. 如果StatementList存在,返回StatementListVarDeclaredNames
  2. 返回一个新的空列表
DefaultClause : default : StatementListopt
  1. 如果StatementList存在,返回StatementListVarDeclaredNames
  2. 返回一个新的空列表
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回VarDeclaredNamesLabelledItem
LabelledItem : FunctionDeclaration
  1. 返回一个新的空列表
TryStatement : try Block Catch
  1. names1VarDeclaredNamesBlock
  2. names2VarDeclaredNamesCatch
  3. 返回 names1names2列表连接
TryStatement : try Block Finally
  1. names1VarDeclaredNamesBlock
  2. names2VarDeclaredNamesFinally
  3. 返回 names1names2列表连接
TryStatement : try Block Catch Finally
  1. names1VarDeclaredNamesBlock
  2. names2VarDeclaredNamesCatch
  3. names3VarDeclaredNamesFinally
  4. 返回 names1names2names3列表连接
Catch : catch ( CatchParameter ) Block
  1. 返回VarDeclaredNamesBlock
FunctionStatementList : [empty]
  1. 返回一个新的空列表
FunctionStatementList : StatementList
  1. 返回TopLevelVarDeclaredNamesStatementList
ClassStaticBlockStatementList : [empty]
  1. 返回一个新的空列表
ClassStaticBlockStatementList : StatementList
  1. 返回TopLevelVarDeclaredNamesStatementList
ConciseBody : ExpressionBody
  1. 返回一个新的空列表
AsyncConciseBody : ExpressionBody
  1. 返回一个新的空列表
Script : [empty]
  1. 返回一个新的空列表
ScriptBody : StatementList
  1. 返回TopLevelVarDeclaredNamesStatementList
ModuleItemList : ModuleItemList ModuleItem
  1. names1VarDeclaredNamesModuleItemList
  2. names2VarDeclaredNamesModuleItem
  3. 返回 names1names2列表连接
ModuleItem : ImportDeclaration
  1. 返回一个新的空列表
ModuleItem : ExportDeclaration
  1. 如果ExportDeclarationexport VariableStatement,返回BoundNamesExportDeclaration
  2. 返回一个新的空列表

8.2.7 静态语义:VarScopedDeclarations

VarScopedDeclarations是一个无需参数并返回List的语法定向操作,其中列表包含Parse Nodes。它通过以下各个产生式逐段定义:

Statement : EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement
  1. 返回一个新的空 List
Block : { }
  1. 返回一个新的空 List
StatementList : StatementList StatementListItem
  1. declarations1VarScopedDeclarations,位于 StatementList
  2. declarations2VarScopedDeclarations,位于 StatementListItem
  3. 返回 list-concatenation 的结果,包括 declarations1declarations2
StatementListItem : Declaration
  1. 返回一个新的空 List
VariableDeclarationList : VariableDeclaration
  1. 返回 « VariableDeclaration »。
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. declarations1VarScopedDeclarationsVariableDeclarationList
  2. 返回 list-concatenationdeclarations1 和 « VariableDeclaration »。
IfStatement : if ( Expression ) Statement else Statement
  1. declarations1VarScopedDeclarations 的第一个 Statement
  2. declarations2VarScopedDeclarations 的第二个 Statement
  3. 返回 list-concatenationdeclarations1declarations2
IfStatement : if ( Expression ) Statement
  1. 返回 StatementVarScopedDeclarations
DoWhileStatement : do Statement while ( Expression ) ;
  1. 返回 StatementVarScopedDeclarations
WhileStatement : while ( Expression ) Statement
  1. 返回 StatementVarScopedDeclarations
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. 返回 StatementVarScopedDeclarations
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. declarations1 成为 VariableDeclarationListVarScopedDeclarations
  2. declarations2 成为 StatementVarScopedDeclarations
  3. 返回 declarations1declarations2list-concatenation
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. 返回 StatementVarScopedDeclarations
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. 返回 StatementVarScopedDeclarations
ForInOfStatement : for ( var ForBinding in Expression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement
  1. declarations1 为 « ForBinding »。
  2. declarations2VarScopedDeclarationsStatement 中的结果。
  3. 返回 declarations1declarations2list-concatenation
注意

本节由附件 B.3.5 扩展。

WithStatement : with ( Expression ) Statement
  1. 返回VarScopedDeclarations Statement的内容。
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回 VarScopedDeclarationsCaseBlock
CaseBlock : { }
  1. 返回一个新的空列表
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 如果第一个CaseClauses存在,则让declarations1成为第一个CaseClausesVarScopedDeclarations
  2. 否则,让declarations1成为一个新的空列表
  3. declarations2成为VarScopedDeclarationsDefaultClause
  4. 如果第二个CaseClauses存在,则让declarations3成为第二个CaseClausesVarScopedDeclarations
  5. 否则,让declarations3成为一个新的空列表
  6. 返回declarations1declarations2declarations3列表连接
CaseClauses : CaseClauses CaseClause
  1. declarations1成为VarScopedDeclarationsCaseClauses
  2. declarations2成为VarScopedDeclarationsCaseClause
  3. 返回declarations1declarations2列表连接
CaseClause : case Expression : StatementListopt
  1. 如果StatementList存在, 返回VarScopedDeclarationsStatementList
  2. 返回一个新的空List
DefaultClause : default : StatementListopt
  1. 如果StatementList存在, 返回VarScopedDeclarationsStatementList
  2. 返回一个新的空List
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回VarScopedDeclarationsLabelledItem
LabelledItem : FunctionDeclaration
  1. 返回一个新的空List
TryStatement : try Block Catch
  1. declarations1VarScopedDeclarationsBlock
  2. declarations2VarScopedDeclarationsCatch
  3. 返回declarations1declarations2list-concatenation
TryStatement : try Block Finally
  1. declarations1设为Block的变量作用域声明。
  2. declarations2设为Finally的变量作用域声明。
  3. 返回declarations1declarations2列表连接
TryStatement : try Block Catch Finally
  1. declarations1设为Block的变量作用域声明。
  2. declarations2设为Catch的变量作用域声明。
  3. declarations3设为Finally的变量作用域声明。
  4. 返回declarations1declarations2declarations3列表连接
Catch : catch ( CatchParameter ) Block
  1. 返回VarScopedDeclarationsBlock
FunctionStatementList : [empty]
  1. 返回一个新的空List
FunctionStatementList : StatementList
  1. 返回TopLevelVarScopedDeclarationsStatementList
ClassStaticBlockStatementList : [empty]
  1. 返回一个新的空List
ClassStaticBlockStatementList : StatementList
  1. 返回TopLevelVarScopedDeclarationsStatementList
ConciseBody : ExpressionBody
  1. 返回一个新的空List
AsyncConciseBody : ExpressionBody
  1. 返回一个新的空List
Script : [empty]
  1. 返回一个新的空List
ScriptBody : StatementList
  1. 返回TopLevelVarScopedDeclarationsStatementList
Module : [empty]
  1. 返回一个新的空List
ModuleItemList : ModuleItemList ModuleItem
  1. declarations1成为VarScopedDeclarationsModuleItemList
  2. declarations2成为VarScopedDeclarationsModuleItem
  3. 返回list-concatenationdeclarations1declarations2
ModuleItem : ImportDeclaration
  1. 返回一个新的空List
ModuleItem : ExportDeclaration
  1. 如果ExportDeclarationexport VariableStatement,返回 VarScopedDeclarationsVariableStatement
  2. 返回一个新的空List

8.2.8 静态语义: TopLevelLexicallyDeclaredNames

语法定向操作 TopLevelLexicallyDeclaredNames 不接受参数并返回一个 字符串列表。它在以下产生式上被分段定义:

StatementList : StatementList StatementListItem
  1. names1设为StatementList的顶层词法声明名称。
  2. names2设为StatementListItem的顶层词法声明名称。
  3. 返回names1names2列表连接
StatementListItem : Statement
  1. 返回一个新的空List
StatementListItem : Declaration
  1. 如果Declaration Declaration : HoistableDeclaration ,则
    1. 返回一个新的空List
  2. 返回BoundNames,属于Declaration
注意

在函数或脚本的顶层,函数声明被视为 var 声明,而不是词法声明。

8.2.9 静态语义: TopLevelLexicallyScopedDeclarations

静态语义操作 TopLevelLexicallyScopedDeclarations 不接受参数,并返回一个 List,其中包含 解析节点。它根据以下产生式逐段定义:

StatementList : StatementList StatementListItem
  1. declarations1 成为 TopLevelLexicallyScopedDeclarationsStatementList
  2. declarations2 成为 TopLevelLexicallyScopedDeclarationsStatementListItem
  3. 返回 list-concatenation, 包含 declarations1declarations2
StatementListItem : Statement
  1. 返回一个新的空 List
StatementListItem : Declaration
  1. 如果 Declaration Declaration : HoistableDeclaration ,那么
    1. 返回一个新的空 List
  2. 返回 « Declaration »。

8.2.10 静态语义: TopLevelVarDeclaredNames

语法定向操作 TopLevelVarDeclaredNames 不接受参数,并返回一个 List,其中包含字符串列表。它在以下产生式上分段定义:

StatementList : StatementList StatementListItem
  1. names1TopLevelVarDeclaredNamesStatementList 的。
  2. names2TopLevelVarDeclaredNamesStatementListItem 的。
  3. 返回 list-concatenationnames1names2
StatementListItem : Declaration
  1. 如果 Declaration Declaration : HoistableDeclaration ,则
    1. 返回 BoundNamesHoistableDeclaration
  2. 返回一个新的空 List
StatementListItem : Statement
  1. 如果 Statement Statement : LabelledStatement ,返回 TopLevelVarDeclaredNamesStatement
  2. 返回 VarDeclaredNamesStatement
注意

在函数或脚本的顶层,内部函数声明被视为 var 声明。

LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 TopLevelVarDeclaredNamesLabelledItem
LabelledItem : Statement
  1. 如果Statement Statement : LabelledStatement ,返回TopLevelVarDeclaredNamesStatement
  2. 返回VarDeclaredNamesStatement
LabelledItem : FunctionDeclaration
  1. 返回FunctionDeclarationFunctionDeclaration

8.2.11 Static Semantics: TopLevelVarScopedDeclarations

The 语法导向操作 TopLevelVarScopedDeclarations 不接受参数并返回一个 列表,其中包含 解析节点。 它在以下各处生效:

StatementList : StatementList StatementListItem
  1. Let declarations1 be TopLevelVarScopedDeclarationsStatementList
  2. Let declarations2 be TopLevelVarScopedDeclarationsStatementListItem
  3. Return 列表连接 declarations1declarations2
StatementListItem : Statement
  1. 如果 Statement Statement : LabelledStatement ,返回 TopLevelVarScopedDeclarationsStatement
  2. 返回 VarScopedDeclarationsStatement
StatementListItem : Declaration
  1. 如果 Declaration Declaration : HoistableDeclaration ,那么
    1. declaration 成为 HoistableDeclarationDeclarationPart
    2. 返回 « declaration »。
  2. 返回一个新的空 List
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 TopLevelVarScopedDeclarations 中的 LabelledItem
LabelledItem : Statement
  1. 如果 Statement Statement : LabelledStatement , 返回 TopLevelVarScopedDeclarations 中的 Statement
  2. 返回 VarScopedDeclarations 中的 Statement
LabelledItem : FunctionDeclaration
  1. 返回 « FunctionDeclaration »。

8.3 Labels

8.3.1 静态语义: 包含重复标签 (ContainsDuplicateLabels)

语法导向操作 ContainsDuplicateLabels 接受参数 labelSet(一个 字符串列表)并返回一个布尔值。它在以下各个产生式上分段定义:

Statement : VariableStatement EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement Block : { } StatementListItem : Declaration
  1. 返回 false
StatementList : StatementList StatementListItem
  1. hasDuplicates 为带有参数 labelSetContainsDuplicateLabelsStatementList 中的结果。
  2. 如果 hasDuplicatestrue,则返回 true
  3. 返回带有参数 labelSetContainsDuplicateLabelsStatementListItem 中的结果。
IfStatement : if ( Expression ) Statement else Statement
  1. hasDuplicate 为带有参数 labelSetContainsDuplicateLabels 在第一个 Statement 中的结果。
  2. 如果 hasDuplicatetrue,则返回 true
  3. 返回带有参数 labelSetContainsDuplicateLabels 在第二个 Statement 中的结果。
IfStatement : if ( Expression ) Statement
  1. 返回带有参数 labelSetContainsDuplicateLabelsStatement 中的结果。
DoWhileStatement : do Statement while ( Expression ) ;
  1. 返回带有参数 labelSetContainsDuplicateLabelsStatement 中的结果。
WhileStatement : while ( Expression ) Statement
  1. 返回带有参数 labelSetContainsDuplicateLabelsStatement 中的结果。
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. 返回带有参数 labelSetContainsDuplicateLabelsStatement 中的结果。
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. 返回带有参数 labelSetContainsDuplicateLabelsStatement 中的结果。
注意

此部分由附录 B.3.5 扩展。

WithStatement : with ( Expression ) Statement
  1. 返回带有参数 labelSetContainsDuplicateLabelsStatement
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回带有参数 labelSetContainsDuplicateLabelsCaseBlock
CaseBlock : { }
  1. 返回 false
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 如果第一个 CaseClauses 存在,则
    1. 如果使用参数 labelSet 调用第一个 CaseClausesContainsDuplicateLabels 返回 true,则返回 true
  2. 如果使用参数 labelSet 调用 ContainsDuplicateLabels 返回第二个 DefaultClause 的结果为 true,则返回 true
  3. 如果第二个 CaseClauses 不存在,则返回 false
  4. 返回使用参数 labelSet 调用第二个 CaseClausesContainsDuplicateLabels
CaseClauses : CaseClauses CaseClause
  1. hasDuplicates 为使用参数 labelSet 调用 ContainsDuplicateLabels 的结果,作用于 CaseClauses
  2. 如果 hasDuplicatestrue,则返回 true
  3. 返回使用参数 labelSet 调用 ContainsDuplicateLabels 的结果,作用于 CaseClause
CaseClause : case Expression : StatementListopt
  1. 如果存在 StatementList,则返回使用参数 labelSet 调用 ContainsDuplicateLabels 的结果,作用于 StatementList
  2. 返回 false
DefaultClause : default : StatementListopt
  1. 如果存在 StatementList,则返回使用参数 labelSet 调用 ContainsDuplicateLabels 的结果,作用于 StatementList
  2. 返回 false
LabelledStatement : LabelIdentifier : LabelledItem
  1. label 设置为 StringValue 的值,来源于 LabelIdentifier
  2. 如果 labelSet 包含 label,则返回 true
  3. newLabelSetlist-concatenation,包含 labelSet 和 « label »。
  4. 返回使用参数 newLabelSet 调用 ContainsDuplicateLabels 的结果,作用于 LabelledItem
LabelledItem : FunctionDeclaration
  1. 返回 false
TryStatement : try Block Catch
  1. hasDuplicates 成为 ContainsDuplicateLabels 用参数 labelSet 计算 Block
  2. 如果 hasDuplicatestrue,则返回 true
  3. 返回 ContainsDuplicateLabels 用参数 labelSet 计算 Catch
TryStatement : try Block Finally
  1. hasDuplicates 成为 ContainsDuplicateLabels 用参数 labelSet 计算 Block
  2. 如果 hasDuplicatestrue,则返回 true
  3. 返回 ContainsDuplicateLabels 用参数 labelSet 计算 Finally
TryStatement : try Block Catch Finally
  1. 如果 ContainsDuplicateLabels 用参数 labelSet 计算 Block 的结果是 true,则返回 true
  2. 如果 ContainsDuplicateLabels 用参数 labelSet 计算 Catch 的结果是 true,则返回 true
  3. 返回 ContainsDuplicateLabels 用参数 labelSet 计算 Finally 的结果。
Catch : catch ( CatchParameter ) Block
  1. 返回 ContainsDuplicateLabels 用参数 labelSet 计算 Block 的结果。
FunctionStatementList : [empty]
  1. 返回 false
ClassStaticBlockStatementList : [empty]
  1. 返回 false.
ModuleItemList : ModuleItemList ModuleItem
  1. hasDuplicates 为带有参数 labelSetContainsDuplicateLabels, 其中 ModuleItemList
  2. 如果 hasDuplicatestrue,则返回 true
  3. 返回带有参数 labelSetContainsDuplicateLabels ,其对应 ModuleItem
ModuleItem : ImportDeclaration ExportDeclaration
  1. 返回 false

8.3.2 静态语义: ContainsUndefinedBreakTarget

语法定向操作 ContainsUndefinedBreakTarget 接受参数 labelSet(一个字符串列表)并返回一个布尔值。它根据以下产生式逐段定义:

Statement : VariableStatement EmptyStatement ExpressionStatement ContinueStatement ReturnStatement ThrowStatement DebuggerStatement Block : { } StatementListItem : Declaration
  1. 返回 false
StatementList : StatementList StatementListItem
  1. hasUndefinedLabels 成为 ContainsUndefinedBreakTarget 应用于参数为 labelSetStatementList
  2. 如果 hasUndefinedLabelstrue,则返回 true
  3. 返回 ContainsUndefinedBreakTarget 应用于参数为 labelSetStatementListItem
IfStatement : if ( Expression ) Statement else Statement
  1. hasUndefinedLabels 成为 ContainsUndefinedBreakTarget 应用于参数为 labelSet 的第一个 Statement
  2. 如果 hasUndefinedLabelstrue,则返回 true
  3. 返回 ContainsUndefinedBreakTarget 应用于参数为 labelSet 的第二个 Statement
IfStatement : if ( Expression ) Statement
  1. 返回 ContainsUndefinedBreakTarget 应用于参数为 labelSetStatement
DoWhileStatement : do Statement while ( Expression ) ;
  1. 返回 ContainsUndefinedBreakTarget 应用于参数为 labelSetStatement
WhileStatement : while ( Expression ) Statement
  1. 返回 ContainsUndefinedBreakTarget 应用于参数为 labelSetStatement
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. 返回 ContainsUndefinedBreakTarget 应用于参数为 labelSetStatement
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. 返回 ContainsUndefinedBreakTarget 应用于参数为 labelSetStatement
注意

此部分由附件 B.3.5 扩展。

BreakStatement : break ;
  1. 返回 false
BreakStatement : break LabelIdentifier ;
  1. 如果 labelSet 不包含 StringValueLabelIdentifier,则返回 true
  2. 返回 false
WithStatement : with ( Expression ) Statement
  1. 返回 ContainsUndefinedBreakTarget 应用于参数为 labelSetStatement
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回 ContainsUndefinedBreakTarget 应用于参数为 labelSetCaseBlock
CaseBlock : { }
  1. 返回false
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 如果第一个CaseClauses存在,则
    1. 如果使用参数labelSet调用ContainsUndefinedBreakTarget 返回true
  2. 如果使用参数labelSet调用ContainsUndefinedBreakTarget 的返回值为true,则返回true
  3. 如果第二个CaseClauses不存在,则返回false
  4. 返回使用参数labelSet调用ContainsUndefinedBreakTarget 的第二个CaseClauses
CaseClauses : CaseClauses CaseClause
  1. hasUndefinedLabelsContainsUndefinedBreakTarget 的返回值,使用参数labelSet调用CaseClauses
  2. 如果hasUndefinedLabelstrue,则返回true
  3. 使用参数labelSet调用ContainsUndefinedBreakTarget 的返回值,使用CaseClause
CaseClause : case Expression : StatementListopt
  1. 如果存在StatementList,则返回使用参数labelSet调用ContainsUndefinedBreakTarget 的返回值,使用StatementList
  2. 返回false
DefaultClause : default : StatementListopt
  1. 如果StatementList存在, 使用参数labelSet调用ContainsUndefinedBreakTarget的返回值,使用StatementList
  2. 返回false
LabelledStatement : LabelIdentifier : LabelledItem
  1. labelStringValue的返回值, 使用LabelIdentifier
  2. newLabelSetlist-concatenation的返回值,使用labelSet和«label »。
  3. 使用参数newLabelSet调用ContainsUndefinedBreakTarget的返回值, 使用LabelledItem
LabelledItem : FunctionDeclaration
  1. 返回false
TryStatement : try Block Catch
  1. hasUndefinedLabelsContainsUndefinedBreakTarget的返回值, 使用BlocklabelSet
  2. 如果hasUndefinedLabelstrue,返回true
  3. 使用CatchlabelSet调用ContainsUndefinedBreakTarget的返回值。
TryStatement : try Block Finally
  1. hasUndefinedLabelsContainsUndefinedBreakTarget的返回值, 使用BlocklabelSet
  2. 如果hasUndefinedLabelstrue,返回true
  3. 使用FinallylabelSet调用ContainsUndefinedBreakTarget的返回值。
TryStatement : try Block Catch Finally
  1. 如果ContainsUndefinedBreakTarget 的返回值为true,使用BlocklabelSet,返回true
  2. 如果ContainsUndefinedBreakTarget 的返回值为true,使用CatchlabelSet,返回true
  3. 使用FinallylabelSet调用ContainsUndefinedBreakTarget的返回值。
Catch : catch ( CatchParameter ) Block
  1. 使用BlocklabelSet调用ContainsUndefinedBreakTarget的返回值。
FunctionStatementList : [空]
  1. 返回false
ClassStaticBlockStatementList : [空]
  1. 返回false
ModuleItemList : ModuleItemList ModuleItem
  1. hasUndefinedLabelsContainsUndefinedBreakTarget 的返回值,使用ModuleItemListlabelSet作为参数。
  2. 如果hasUndefinedLabelstrue,返回true
  3. 使用ModuleItemlabelSet作为参数,调用ContainsUndefinedBreakTarget的返回值。
ModuleItem : ImportDeclaration ExportDeclaration
  1. 返回false

8.3.3 静态语义: ContainsUndefinedContinueTarget

语法定向操作 ContainsUndefinedContinueTarget 接受参数 iterationSet(一个字符串列表)和 labelSet(一个字符串列表),返回一个布尔值。它根据以下产生式逐段定义:

Statement : VariableStatement EmptyStatement ExpressionStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement Block : { } StatementListItem : Declaration
  1. 返回 false
Statement : BlockStatement
  1. 返回 ContainsUndefinedContinueTarget 对于 BlockStatement 的结果,参数为 iterationSet 和 « »。
BreakableStatement : IterationStatement
  1. newIterationSetlist-concatenation 的结果,参数为 iterationSetlabelSet
  2. 返回 ContainsUndefinedContinueTarget 对于 IterationStatement 的结果,参数为 newIterationSet 和 « »。
StatementList : StatementList StatementListItem
  1. hasUndefinedLabelsContainsUndefinedContinueTarget 对于 StatementList 的结果,参数为 iterationSet 和 « »。
  2. 如果 hasUndefinedLabelstrue,则返回 true
  3. 返回 ContainsUndefinedContinueTarget 对于第二个 Statement 的结果,参数为 iterationSet 和 « »。
IfStatement : if ( Expression ) Statement else Statement
  1. hasUndefinedLabelsContainsUndefinedContinueTarget 对于第一个 Statement 的结果,参数为 iterationSet 和 « »。
  2. 如果 hasUndefinedLabelstrue,则返回 true
  3. 返回 ContainsUndefinedContinueTarget 对于第二个 Statement 的结果,参数为 iterationSet 和 « »。
IfStatement : if ( Expression ) Statement
  1. 返回 ContainsUndefinedContinueTarget 对于 Statement 的结果,参数为 iterationSet 和 « »。
DoWhileStatement : do Statement while ( Expression ) ;
  1. 返回 ContainsUndefinedContinueTarget 对于 Statement 的结果,参数为 iterationSet 和 « »。
WhileStatement : while ( Expression ) Statement
  1. 返回 ContainsUndefinedContinueTarget 对于 Statement 的结果,参数为 iterationSet 和 « »。
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. 返回使用参数 iterationSet 和 « » 的 ContainsUndefinedContinueTargetStatement 进行调用。
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. 返回使用参数 iterationSet 和 « » 的 ContainsUndefinedContinueTargetStatement 进行调用。
注意

本节由附录 B.3.5 扩展。

ContinueStatement : continue ;
  1. 返回 false
ContinueStatement : continue LabelIdentifier ;
  1. 如果 iterationSet 不包含 LabelIdentifierStringValue,则返回 true
  2. 返回 false
WithStatement : with ( Expression ) Statement
  1. 返回使用参数 iterationSet 和 « » 的 ContainsUndefinedContinueTargetStatement 进行调用。
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回使用参数 iterationSet 和 « » 的 ContainsUndefinedContinueTargetCaseBlock 进行调用。
CaseBlock : { }
  1. 返回 false
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 如果第一个 CaseClauses 存在,则
    1. 如果 ContainsUndefinedContinueTarget 对第一个带参数 iterationSet 和 « » 的 CaseClauses 返回 true,则返回 true
  2. 如果 ContainsUndefinedContinueTarget 对带参数 iterationSet 和 « » 的 DefaultClause 返回 true,则返回 true
  3. 如果第二个 CaseClauses 不存在,则返回 false
  4. 返回使用参数 iterationSet 和 « » 的第二个 CaseClausesContainsUndefinedContinueTarget
CaseClauses : CaseClauses CaseClause
  1. hasUndefinedLabels 等于使用参数 iterationSet 和 « » 的 ContainsUndefinedContinueTargetCaseClauses 进行调用。
  2. 如果 hasUndefinedLabelstrue,则返回 true
  3. 返回使用参数 iterationSet 和 « » 的 ContainsUndefinedContinueTargetCaseClause 进行调用。
CaseClause : case Expression : StatementListopt
  1. 如果存在 StatementList,则返回使用参数 iterationSet 和 « » 的 ContainsUndefinedContinueTargetStatementList 进行调用。
  2. 返回 false
DefaultClause : default : StatementListopt
  1. 如果存在 StatementList,则返回使用参数 iterationSet 和 « » 的 ContainsUndefinedContinueTargetStatementList 进行调用。
  2. 返回 false
LabelledStatement : LabelIdentifier : LabelledItem
  1. labelLabelIdentifierStringValue
  2. newLabelSetlabelSet 和 « label » 的 list-concatenation
  3. 返回使用参数 iterationSetnewLabelSetContainsUndefinedContinueTargetLabelledItem 进行调用。
LabelledItem : FunctionDeclaration
  1. 返回 false
TryStatement : try Block Catch
  1. hasUndefinedLabels 为使用参数 iterationSet 和 « » 调用 ContainsUndefinedContinueTargetBlock 的结果。
  2. 如果 hasUndefinedLabelstrue,则返回 true
  3. 返回使用参数 iterationSet 和 « » 调用 ContainsUndefinedContinueTargetCatch 的结果。
TryStatement : try Block Finally
  1. hasUndefinedLabels 为使用参数 iterationSet 和 « » 调用 ContainsUndefinedContinueTargetBlock 的结果。
  2. 如果 hasUndefinedLabelstrue,则返回 true
  3. 返回使用参数 iterationSet 和 « » 调用 ContainsUndefinedContinueTargetFinally 的结果。
TryStatement : try Block Catch Finally
  1. 如果使用参数 iterationSet 和 « » 调用 ContainsUndefinedContinueTargetBlock 的结果为 true,则返回 true
  2. 如果使用参数 iterationSet 和 « » 调用 ContainsUndefinedContinueTargetCatch 的结果为 true,则返回 true
  3. 返回使用参数 iterationSet 和 « » 调用 ContainsUndefinedContinueTargetFinally 的结果。
Catch : catch ( CatchParameter ) Block
  1. 返回使用参数 iterationSet 和 « » 调用 ContainsUndefinedContinueTargetBlock 的结果。
FunctionStatementList : [empty]
  1. 返回 false
ClassStaticBlockStatementList : [empty]
  1. 返回 false
ModuleItemList : ModuleItemList ModuleItem
  1. hasUndefinedLabels 成为使用参数 iterationSet 和 « » 调用 ContainsUndefinedContinueTargetModuleItemList 的结果。
  2. 如果 hasUndefinedLabelstrue,则返回 true
  3. 返回使用参数 iterationSet 和 « » 调用 ContainsUndefinedContinueTargetModuleItem 的结果。
ModuleItem : ImportDeclaration ExportDeclaration
  1. 返回 false

8.4 函数名称推断

8.4.1 静态语义:HasName

语法定向操作 HasName 不接受任何参数并返回一个布尔值。它在以下各个生成式上逐块定义:

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprParenthesizedExpression,它被 CoverParenthesizedExpressionAndArrowParameterList 覆盖
  2. 如果 exprIsFunctionDefinitionfalse,则返回 false
  3. 返回 exprHasName
FunctionExpression : function ( FormalParameters ) { FunctionBody } GeneratorExpression : function * ( FormalParameters ) { GeneratorBody } AsyncGeneratorExpression : async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionExpression : async function ( FormalParameters ) { AsyncFunctionBody } ArrowFunction : ArrowParameters => ConciseBody AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody ClassExpression : class ClassTail
  1. 返回 false
FunctionExpression : function BindingIdentifier ( FormalParameters ) { FunctionBody } GeneratorExpression : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionExpression : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } ClassExpression : class BindingIdentifier ClassTail
  1. 返回 true.

8.4.2 静态语义:IsFunctionDefinition

语法导向操作 IsFunctionDefinition 不接受任何参数,返回一个布尔值。它在以下产生式上逐步定义:

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprParenthesizedExpression,它是由 CoverParenthesizedExpressionAndArrowParameterList 覆盖 的表达式。
  2. 返回 exprIsFunctionDefinition
PrimaryExpression : this IdentifierReference Literal ArrayLiteral ObjectLiteral RegularExpressionLiteral TemplateLiteral MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression LogicalANDExpression : LogicalANDExpression && BitwiseORExpression LogicalORExpression : LogicalORExpression || LogicalANDExpression CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression AssignmentExpression : YieldExpression LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression Expression : Expression , AssignmentExpression
  1. 返回 false.
AssignmentExpression : ArrowFunction AsyncArrowFunction FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody } ClassExpression : class BindingIdentifieropt ClassTail
  1. 返回 true.

8.4.3 静态语义:IsAnonymousFunctionDefinition ( expr )

抽象操作 IsAnonymousFunctionDefinition 接受参数 expr(一个 AssignmentExpression 解析节点,一个 Initializer 解析节点,或一个 Expression 解析节点)并返回一个布尔值。它确定其参数是否为不绑定名称的函数定义。当调用时执行以下步骤:

  1. 如果 exprIsFunctionDefinition 返回 false,则返回 false
  2. hasNameexprHasName
  3. 如果 hasName 返回 true,则返回 false
  4. 返回 true

8.4.4 静态语义:IsIdentifierRef

语法定向操作 IsIdentifierRef 不接受任何参数并返回一个布尔值。它在以下各个生成式中逐段定义:

PrimaryExpression : IdentifierReference
  1. 返回 true.
PrimaryExpression : this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral CoverParenthesizedExpressionAndArrowParameterList MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression
  1. 返回 false.

8.4.5 运行时语义:NamedEvaluation

语法定向操作 NamedEvaluation 接受参数 name(一个 属性键 或一个 私有名称)并返回一个 包含 一个 函数对象 的正常完成记录或一个 异常完成。它在以下各个生成式中逐段定义:

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprParenthesizedExpression,它被 覆盖CoverParenthesizedExpressionAndArrowParameterList 中。
  2. 返回 ? NamedEvaluationname 作为参数调用 expr
ParenthesizedExpression : ( Expression )
  1. 断言: IsAnonymousFunctionDefinition(Expression) 为 true
  2. 返回 ? NamedEvaluationname 作为参数调用 Expression
FunctionExpression : function ( FormalParameters ) { FunctionBody }
  1. 返回 InstantiateOrdinaryFunctionExpressionname 作为参数调用 FunctionExpression
GeneratorExpression : function * ( FormalParameters ) { GeneratorBody }
  1. 返回 InstantiateGeneratorFunctionExpressionname 作为参数调用 GeneratorExpression
AsyncGeneratorExpression : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. 返回 InstantiateAsyncGeneratorFunctionExpressionname 作为参数调用 AsyncGeneratorExpression
AsyncFunctionExpression : async function ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 InstantiateAsyncFunctionExpressionname 作为参数调用 AsyncFunctionExpression
ArrowFunction : ArrowParameters => ConciseBody
  1. 返回 InstantiateArrowFunctionExpressionname 作为参数调用 ArrowFunction
AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. 返回 InstantiateAsyncArrowFunctionExpressionname 作为参数调用 AsyncArrowFunction
ClassExpression : class ClassTail
  1. value 为 ? ClassDefinitionEvaluationClassTail 和参数 undefined 以及 name 调用。
  2. value.[[SourceText]] 设置为 ClassExpression 匹配的源文本。
  3. 返回 value

8.5 包含

8.5.1 静态语义:Contains

语法指导操作 Contains 接受参数 symbol(一个语法符号)并返回一个布尔值。

本规范中未列出的每个语法生成替代方案都隐含具有以下默认的 Contains 定义:

  1. 对于此 解析节点 的每个子节点 child,执行以下操作:
    1. 如果 childsymbol 的一个实例,返回 true
    2. 如果 child 是一个非终结符的实例,那么:
      1. containedchild 结果的 Contains symbol
      2. 如果 containedtrue,返回 true
  2. 返回 false
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 false
注释 1

依赖于子结构的静态语义规则通常不会深入查看函数定义。

ClassTail : ClassHeritageopt { ClassBody }
  1. 如果 symbolClassBody,则返回 true
  2. 如果 symbolClassHeritage,则
    1. 如果 ClassHeritage 存在,则返回 true;否则返回 false
  3. 如果 ClassHeritage 存在,则
    1. 如果 ClassHeritage Contains symboltrue,则返回 true
  4. 返回 ComputedPropertyContains 的结果,其参数为 symbol,在 ClassBody 中。
Note 2

Static semantic rules that depend upon substructure generally do not look into class bodies except for PropertyNames.

ClassStaticBlock : static { ClassStaticBlockBody }
  1. 返回 false
Note 3

依赖子结构的静态语义规则通常不会检查static初始化块。

ArrowFunction : ArrowParameters => ConciseBody
  1. 如果 symbol 不是 NewTargetSuperPropertySuperCallsuperthis 之一,则返回 false
  2. 如果 ArrowParameters Contains symboltrue,则返回 true
  3. 返回 ConciseBody Contains symbol
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsArrowFormalParameters,该 CoverParenthesizedExpressionAndArrowParameterList覆盖
  2. 返回 formals Contains symbol 的结果。
AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody
  1. 如果 symbol 不是以下之一:NewTargetSuperPropertySuperCallsuper,或 this,返回 false
  2. 返回 AsyncConciseBodyContains symbol 的结果。
AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. 如果 symbol 不是以下之一:NewTargetSuperPropertySuperCallsuper,或 this,返回 false
  2. headAsyncArrowHead,它被 CoverCallExpressionAndAsyncArrowHead 覆盖
  3. 如果 head Contains symbol 的结果为 true,返回 true
  4. 返回 AsyncConciseBody Contains symbol 的结果。
Note 4

Contains is used to detect new.target, this, and super usage within an ArrowFunction or AsyncArrowFunction.

PropertyDefinition : MethodDefinition
  1. 如果 symbolMethodDefinition,返回 true
  2. 返回 MethodDefinition ComputedPropertyContains symbol 的结果。
LiteralPropertyName : IdentifierName
  1. 返回 false
MemberExpression : MemberExpression . IdentifierName
  1. 如果 MemberExpression Contains symboltrue,返回 true
  2. 返回 false
SuperProperty : super . IdentifierName
  1. 如果 symbolReservedWord super,返回 true
  2. 返回 false
CallExpression : CallExpression . IdentifierName
  1. 如果 CallExpression Contains symboltrue,返回 true
  2. 返回 false
OptionalChain : ?. IdentifierName
  1. 返回 false
OptionalChain : OptionalChain . IdentifierName
  1. 如果 OptionalChain Contains symboltrue,返回 true
  2. 返回 false

8.5.2 静态语义:ComputedPropertyContains

语法定向操作 ComputedPropertyContains 接受参数 symbol(一个语法符号)并返回一个布尔值。它通过以下生成式逐步定义:

ClassElementName : PrivateIdentifier PropertyName : LiteralPropertyName
  1. 返回 false
PropertyName : ComputedPropertyName
  1. 返回 ComputedPropertyName 的结果,其中 symbol 被作为 Contains 的参数。
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. 返回 ComputedPropertyContains 的结果,其中 ClassElementName 被作为参数 symbol
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. 返回 ComputedPropertyContains 的结果,其中 ClassElementName 被作为参数 symbol
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. 返回 ComputedPropertyContains 的结果,其中 ClassElementName 被作为参数 symbol
ClassElementList : ClassElementList ClassElement
  1. inListComputedPropertyContains 的结果,其中 ClassElementList 被作为参数 symbol
  2. 如果 inListtrue,则返回 true
  3. 返回 ComputedPropertyContains 的结果,其中 ClassElement 被作为参数 symbol
ClassElement : ClassStaticBlock
  1. 返回 false
ClassElement : ;
  1. 返回 false
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. 返回 ComputedPropertyContains 的结果,其中 ClassElementName 被作为参数 symbol
FieldDefinition : ClassElementName Initializeropt
  1. 返回 ComputedPropertyContains 的结果,其中 ClassElementName 被作为参数 symbol

8.6 杂项

这些操作在整个规范的多个地方使用。

8.6.1 运行时语义: InstantiateFunctionObject

语法导向操作 InstantiateFunctionObject 接受参数 env(一个 环境记录)和 privateEnv(一个 私有环境记录null)并返回一个 ECMAScript 函数对象。它按以下生成规则定义:

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody }
  1. 返回 InstantiateOrdinaryFunctionObjectFunctionDeclaration 的调用,参数为 envprivateEnv
GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody }
  1. 返回 InstantiateGeneratorFunctionObjectGeneratorDeclaration 的调用,参数为 envprivateEnv
AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. 返回 InstantiateAsyncGeneratorFunctionObjectAsyncGeneratorDeclaration 的调用,参数为 envprivateEnv
AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 InstantiateAsyncFunctionObjectAsyncFunctionDeclaration 的调用,参数为 envprivateEnv

8.6.2 运行时语义:绑定初始化

语法指导操作 BindingInitialization 接受参数 value(一个ECMAScript 语言值)和 environment(一个环境记录undefined)并返回一个包含 unused 的正常完成或一个突然完成

注意

undefined 被传递给 environment 以表明应该使用PutValue操作来分配初始化值。对于var 语句和一些非严格函数的形式参数列表(参见10.2.11)来说就是这种情况。在这些情况下,词法绑定在其初始化器评估之前被提升和预初始化。

它在以下生成式中逐段定义:

BindingIdentifier : Identifier
  1. name 成为 StringValueIdentifier
  2. 返回 ? InitializeBoundName(name, value, environment)。
BindingIdentifier : yield
  1. 返回 ? InitializeBoundName("yield", value, environment)。
BindingIdentifier : await
  1. 返回 ? InitializeBoundName("await", value, environment)。
BindingPattern : ObjectBindingPattern
  1. 执行 ? RequireObjectCoercible(value)。
  2. 返回 ? BindingInitialization of ObjectBindingPattern with arguments valueenvironment
BindingPattern : ArrayBindingPattern
  1. iteratorRecord 为 ? GetIterator(value, sync)。
  2. resultCompletion(IteratorBindingInitialization of ArrayBindingPattern with arguments iteratorRecordenvironment)。
  3. 如果 iteratorRecord.[[Done]]false,返回 ? IteratorClose(iteratorRecord, result)。
  4. 返回 ? result
ObjectBindingPattern : { }
  1. 返回 unused
ObjectBindingPattern : { BindingPropertyList } { BindingPropertyList , }
  1. 执行 ? PropertyBindingInitialization of BindingPropertyList with arguments valueenvironment
  2. 返回 unused
ObjectBindingPattern : { BindingRestProperty }
  1. excludedNames 成为一个新的空列表
  2. 返回 ? RestBindingInitialization of BindingRestProperty with arguments value, environment, 和 excludedNames
ObjectBindingPattern : { BindingPropertyList , BindingRestProperty }
  1. excludedNames 成为 ? PropertyBindingInitialization of BindingPropertyList with arguments valueenvironment
  2. 返回 ? RestBindingInitialization of BindingRestProperty with arguments value, environment, 和 excludedNames

8.6.2.1 InitializeBoundName ( name, value, environment )

抽象操作 InitializeBoundName 接受参数 name(字符串),value(一个 ECMAScript 语言值),和 environment(一个 环境记录undefined)并返回一个 正常完成记录包含 unused 或者一个 异常完成。它在调用时执行以下步骤:

  1. 如果 environment 不是 undefined,那么
    1. 执行 ! environment.InitializeBinding(name, value)。
    2. 返回 unused
  2. 否则,
    1. lhs 等于 ? ResolveBinding(name)。
    2. 返回 ? PutValue(lhs, value)。

8.6.3 运行时语义:IteratorBindingInitialization

语法指引操作 IteratorBindingInitialization 接受参数 iteratorRecord(一个 迭代器记录)和 environment(一个 环境记录undefined)并返回一个 正常完成记录(包含 unused)或者一个 异常完成记录

environment 被传递为 undefined 时,表示应该使用 PutValue 操作来分配初始化值。这种情况出现在 非严格函数 的形式参数列表中。在这种情况下,形式参数绑定会被预初始化,以处理具有相同名称的多个参数的可能性。

它通过以下生成式逐段定义:

ArrayBindingPattern : [ ]
  1. 返回 unused
ArrayBindingPattern : [ Elision ]
  1. 返回 ? IteratorDestructuringAssignmentEvaluation of Elision with argument iteratorRecord
ArrayBindingPattern : [ Elisionopt BindingRestElement ]
  1. 如果 Elision 存在,那么
    1. 执行 ? IteratorDestructuringAssignmentEvaluation of Elision with argument iteratorRecord
  2. 返回 ? IteratorBindingInitialization of BindingRestElement with arguments iteratorRecordenvironment
ArrayBindingPattern : [ BindingElementList , Elision ]
  1. 执行 ? IteratorBindingInitialization of BindingElementList with arguments iteratorRecordenvironment
  2. 返回 ? IteratorDestructuringAssignmentEvaluation of Elision with argument iteratorRecord
ArrayBindingPattern : [ BindingElementList , Elisionopt BindingRestElement ]
  1. 执行 ? IteratorBindingInitialization of BindingElementList with arguments iteratorRecordenvironment
  2. 如果 Elision 存在,那么
    1. 执行 ? IteratorDestructuringAssignmentEvaluation of Elision with argument iteratorRecord
  3. 返回 ? IteratorBindingInitialization of BindingRestElement with arguments iteratorRecordenvironment
BindingElementList : BindingElementList , BindingElisionElement
  1. 执行 ? IteratorBindingInitialization of BindingElementList with arguments iteratorRecordenvironment
  2. 返回 ? IteratorBindingInitialization of BindingElisionElement with arguments iteratorRecordenvironment
BindingElisionElement : Elision BindingElement
  1. 执行 ? IteratorDestructuringAssignmentEvaluation of Elision with argument iteratorRecord
  2. 返回 ? IteratorBindingInitialization of BindingElement with arguments iteratorRecordenvironment
单名称绑定(SingleNameBinding) : 绑定标识符(BindingIdentifier) 初始化器(Initializer) opt
  1. bindingId 字符串值(StringValue) 绑定标识符(BindingIdentifier)
  2. lhs 为 ?  解析绑定(ResolveBinding) (bindingId, environment)。
  3. v未定义(undefined)
  4. 如果 iteratorRecord[[完成]]([[Done]])false,则:
    1. next 为 ?  迭代器步骤值(IteratorStepValue) (iteratorRecord)。
    2. 如果 next 不是 完成(done),则:
      1. v 设为 next
  5. 如果存在 初始化器(Initializer) v未定义(undefined),则:
    1. 如果 是否匿名函数定义(IsAnonymousFunctionDefinition) ( 初始化器(Initializer) ) 为 true,则:
      1. v 设为 ?  命名评估(NamedEvaluation) ( 初始化器(Initializer) ,参数为 bindingId)。
    2. 否则:
      1. defaultValue 为 ?  评估(Evaluation) ( 初始化器(Initializer) )。
      2. v 设为 ?  获取值(GetValue) (defaultValue)。
  6. 如果 environment未定义(undefined), 则返回 ?  放置值(PutValue) (lhsv)。
  7. 返回 ?  初始化引用绑定(InitializeReferencedBinding) (lhsv)。
绑定元素(BindingElement) : 绑定模式(BindingPattern) 初始化器(Initializer) opt
  1. v未定义(undefined)
  2. 如果 iteratorRecord[[完成]]([[Done]])false,则:
    1. next 为 ?  迭代器步骤值(IteratorStepValue) (iteratorRecord)。
    2. 如果 next 不是 完成(done),则:
      1. v 设为 next
  3. 如果存在 初始化器(Initializer) v未定义(undefined),则:
    1. defaultValue 为 ?  评估(Evaluation) ( 初始化器(Initializer) )。
    2. v 设为 ?  获取值(GetValue) (defaultValue)。
  4. 返回 ?  绑定初始化(BindingInitialization) 绑定模式(BindingPattern) ,参数为 venvironment
BindingRestElement : ... BindingIdentifier
  1. lhs 为 ?  ResolveBinding ( StringValue BindingIdentifier , environment)。
  2. A 为 !  ArrayCreate (0)。
  3. n 为 0。
  4. 重复,
    1. nextdone
    2. 如果 iteratorRecord[[Done]]false,则:
      1. next 设为 ?  IteratorStepValue (iteratorRecord)。
    3. 如果 nextdone,则:
      1. 如果 environmentundefined,则返回 ?  PutValue (lhs, A)。
      2. 返回 ?  InitializeReferencedBinding (lhs, A)。
    4. 执行 !  CreateDataPropertyOrThrow (A, !  ToString ( 𝔽 (n)), next)。
    5. n 设为 n + 1。
BindingRestElement : ... BindingPattern
  1. A 为 !  ArrayCreate (0)。
  2. n 为 0。
  3. 重复,
    1. nextdone
    2. 如果 iteratorRecord[[Done]]false,则:
      1. next 设为 ?  IteratorStepValue (iteratorRecord)。
    3. 如果 nextdone,则:
      1. 返回 ?  BindingInitialization of BindingPattern ,参数为 Aenvironment
    4. 执行 !  CreateDataPropertyOrThrow (A, !  ToString ( 𝔽 (n)), next)。
    5. n 设为 n + 1。
FormalParameters : [empty]
  1. 返回 unused
FormalParameters : FormalParameterList , FunctionRestParameter
  1. 执行 ?  IteratorBindingInitialization of FormalParameterList ,参数为 iteratorRecordenvironment
  2. 返回 ?  IteratorBindingInitialization of FunctionRestParameter ,参数为 iteratorRecordenvironment
FormalParameterList : FormalParameterList , FormalParameter
  1. 执行 ?  IteratorBindingInitialization of FormalParameterList ,参数为 iteratorRecordenvironment
  2. 返回 ?  IteratorBindingInitialization of FormalParameter ,参数为 iteratorRecordenvironment
ArrowParameters : BindingIdentifier
  1. vundefined
  2. 断言 iteratorRecord.[[Done]]false
  3. next 为 ?  IteratorStepValue (iteratorRecord)。
  4. 如果 next 不是 done,则
    1. v 设置为 next
  5. 返回 ?  BindingInitialization of BindingIdentifier ,参数为 venvironment
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsArrowFormalParameters ,它被 CoverParenthesizedExpressionAndArrowParameterList 所覆盖。
  2. 返回 ?  IteratorBindingInitialization of formals,参数为 iteratorRecordenvironment
AsyncArrowBindingIdentifier : BindingIdentifier
  1. vundefined
  2. 断言 iteratorRecord.[[Done]]false
  3. next 为 ?  IteratorStepValue (iteratorRecord)。
  4. 如果 next 不是 done,则
    1. v 设置为 next
  5. 返回 ?  BindingInitialization of BindingIdentifier ,参数为 venvironment

8.6.4 静态语义: AssignmentTargetType

语法指导操作 AssignmentTargetType 不接受参数,返回 simpleinvalid。它在以下各个产生式上被分段定义:

IdentifierReference : Identifier
  1. 如果这个 IdentifierReference 包含在 严格模式代码 中,并且 IdentifierStringValue"eval""arguments",则返回 invalid
  2. 返回 simple
IdentifierReference : yield await CallExpression : CallExpression [ Expression ] CallExpression . IdentifierName CallExpression . PrivateIdentifier MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName SuperProperty MemberExpression . PrivateIdentifier
  1. 返回 simple
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. expr 是由 ParenthesizedExpression包含 的部分。
  2. 返回 AssignmentTargetTypeexpr
PrimaryExpression : this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral CallExpression : CoverCallExpressionAndAsyncArrowHead SuperCall ImportCall CallExpression Arguments CallExpression TemplateLiteral NewExpression : new NewExpression MemberExpression : MemberExpression TemplateLiteral new MemberExpression Arguments NewTarget : new . target ImportMeta : import . meta LeftHandSideExpression : OptionalExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression LogicalANDExpression : LogicalANDExpression && BitwiseORExpression LogicalORExpression : LogicalORExpression || LogicalANDExpression CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression AssignmentExpression : YieldExpression ArrowFunction AsyncArrowFunction LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression Expression : Expression , AssignmentExpression
  1. 返回 invalid

8.6.5 静态语义:PropName

语法导向操作 PropName 不接受任何参数,并返回一个字符串或 empty。它在以下生成式上逐步定义:

PropertyDefinition : IdentifierReference
  1. 返回 StringValueIdentifierReference
PropertyDefinition : ... AssignmentExpression
  1. 返回 empty.
PropertyDefinition : PropertyName : AssignmentExpression
  1. 返回 PropNamePropertyName
LiteralPropertyName : IdentifierName
  1. 返回 StringValueIdentifierName
LiteralPropertyName : StringLiteral
  1. 返回 SVStringLiteral
LiteralPropertyName : NumericLiteral
  1. nbrNumericValueNumericLiteral
  2. 返回 ! ToString(nbr)。
ComputedPropertyName : [ AssignmentExpression ]
  1. 返回 empty
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. 返回 PropNameClassElementName
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. 返回 PropNameClassElementName
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. 返回 PropNameClassElementName
ClassElement : ClassStaticBlock
  1. 返回 empty.
ClassElement : ;
  1. 返回 empty.
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. 返回 PropNameClassElementName
FieldDefinition : ClassElementName Initializeropt
  1. 返回 PropNameClassElementName
ClassElementName : PrivateIdentifier
  1. 返回 empty

9 可执行代码和执行上下文

9.1 环境记录

环境记录是一种规范类型,用于根据 ECMAScript 代码的词法嵌套结构,定义标识符与特定变量和函数的关联。通常,环境记录与 ECMAScript 代码的某些特定语法结构相关联,如函数声明块语句捕获子句等。每次评估此类代码时,都会创建一个新的环境记录来记录该代码创建的标识符绑定。

每个环境记录都有一个[[OuterEnv]]字段,它要么是null,要么是对外部环境记录的引用。这用于模拟环境记录值的逻辑嵌套。内部环境记录的外部引用是对逻辑上包围内部环境记录的外部环境记录的引用。当然,外部环境记录可能有其自己的外部环境记录。一个环境记录可能作为多个内部环境记录的外部环境。例如,如果一个函数声明包含两个嵌套的函数声明,那么每个嵌套函数的环境记录的外部环境记录将是当前评估的包围函数的环境记录。

环境记录纯粹是规范机制,不需要对应于 ECMAScript 实现的任何具体产物。ECMAScript 程序不可能直接访问或操作这些值。

9.1.1 环境记录类型层次结构

环境记录 可以被认为存在于一个简单的面向对象层次结构中,其中 环境记录 是一个具有三个具体子类的抽象类:声明式环境记录对象环境记录全局环境记录函数环境记录模块环境记录声明式环境记录 的子类。

环境记录抽象类包括表16中定义的抽象规范方法。这些抽象方法对每个具体子类都有不同的具体算法。

表16: 环境记录的抽象方法
方法 用途
HasBinding(N) 确定环境记录是否有字符串值N的绑定。如果有,返回true,否则返回false
CreateMutableBinding(N, D) 环境记录中创建一个新的但未初始化的可变绑定。字符串值N是绑定名的文本。如果布尔参数Dtrue,则绑定可能会被随后删除。
CreateImmutableBinding(N, S) 环境记录中创建一个新的但未初始化的不可变绑定。字符串值N是绑定名的文本。如果Strue,则在初始化后尝试设置它总是会抛出异常,无论引用该绑定的操作的严格模式设置如何。
InitializeBinding(N, V) 设置环境记录中已存在但未初始化的绑定的值。字符串值N是绑定名的文本。V是绑定的值,可以是任何ECMAScript 语言类型的值。
SetMutableBinding(N, V, S) 设置环境记录中已存在的可变绑定的值。字符串值N是绑定名的文本。V是绑定的值,可以是任何ECMAScript 语言类型的值。S是一个布尔标志。如果Strue并且绑定不能设置,则抛出TypeError异常。
GetBindingValue(N, S) 返回环境记录中已存在绑定的值。字符串值N是绑定名的文本。S用于标识源自严格模式代码或其他需要严格模式引用语义的引用。如果Strue且绑定不存在,则抛出ReferenceError异常。如果绑定存在但未初始化,则无论S的值如何,都会抛出ReferenceError
DeleteBinding(N) 环境记录中删除一个绑定。字符串值N是绑定名的文本。如果存在N的绑定,则移除绑定并返回true。如果绑定存在但无法移除,则返回false。如果绑定不存在,则返回true
HasThisBinding() 确定环境记录是否建立了this绑定。如果建立了,返回true,否则返回false
HasSuperBinding() 确定环境记录是否建立了super方法绑定。如果建立了,返回true,否则返回false
WithBaseObject() 如果此环境记录with语句关联,则返回 with 对象。否则,返回undefined

9.1.1.1 声明式环境记录

每个声明式环境记录都与包含变量、常量、let、class、模块、import和/或函数声明的 ECMAScript 程序范围相关联。声明式环境记录绑定其范围内包含的声明所定义的一组标识符。

声明式环境记录的具体规范方法的行为由以下算法定义。

9.1.1.1.1 HasBinding ( N )

声明式环境记录 envRec的 HasBinding 具体方法接受参数N(一个字符串)并返回一个包含布尔值的正常完成记录。它确定参数标识符是否是记录绑定的标识符之一。调用时执行以下步骤:

  1. 如果envRecN的绑定,则返回true
  2. 返回false

9.1.1.1.2 CreateMutableBinding ( N, D )

声明式环境记录 envRec的 CreateMutableBinding 具体方法接受参数N(一个字符串)和D(一个布尔值),并返回一个包含 unused的正常完成记录。它为名称N创建一个新的未初始化的可变绑定。环境记录中不应已有N的绑定。如果Dtrue,则新绑定被标记为可以删除。调用时执行以下步骤:

  1. 断言envRec中不存在N的绑定。
  2. envRec中为N创建一个可变绑定,并记录它未初始化。如果Dtrue,则记录新创建的绑定可以通过后续的 DeleteBinding 调用删除。
  3. 返回unused

9.1.1.1.3 CreateImmutableBinding ( N, S )

声明式环境记录 envRec的 CreateImmutableBinding 具体方法接受参数N(一个字符串)和S(一个布尔值),并返回一个包含 unused的正常完成记录。它为名称N创建一个新的未初始化的不可变绑定。环境记录中不应已有N的绑定。如果Strue,则新绑定被标记为严格绑定。调用时执行以下步骤:

  1. 断言envRec中不存在N的绑定。
  2. envRec中为N创建一个不可变绑定,并记录它未初始化。如果Strue,则记录新创建的绑定是严格绑定。
  3. 返回unused

9.1.1.1.4 InitializeBinding ( N, V )

声明式环境记录 envRec的 InitializeBinding 具体方法接受参数N(一个字符串)和V(一个ECMAScript 语言值),并返回一个包含 unused的正常完成记录。它用于将名称为N的标识符的当前绑定值设置为V。必须已存在N的未初始化绑定。调用时执行以下步骤:

  1. 断言envRec中必须有N的未初始化绑定。
  2. envRecN的绑定值设置为V
  3. 记录envRecN的绑定已被初始化。
  4. 返回unused

9.1.1.1.5 SetMutableBinding ( N, V, S )

声明式环境记录 envRec的 SetMutableBinding 具体方法接受参数N(一个字符串)、V(一个ECMAScript 语言值)和S(一个布尔值),并返回一个包含 unused的正常完成记录或一个抛出完成记录。它尝试将名称为N的标识符的当前绑定值更改为V。通常情况下,已经存在N的绑定,但在极少数情况下可能不存在。如果绑定是不可变绑定,则如果Strue,会抛出TypeError。调用时执行以下步骤:

  1. 如果envRec中没有N的绑定,则
    1. 如果Strue,抛出ReferenceError异常。
    2. 执行 ! envRec.CreateMutableBinding(N, true)。
    3. 执行 ! envRec.InitializeBinding(N, V)。
    4. 返回unused
  2. 如果envRecN的绑定是严格绑定,则将S设置为true
  3. 如果envRecN的绑定尚未初始化,则
    1. 抛出ReferenceError异常。
  4. 否则,如果envRecN的绑定是可变绑定,则
    1. 将其绑定值更改为V
  5. 否则,
    1. 断言:这是尝试更改不可变绑定的值。
    2. 如果Strue,抛出TypeError异常。
  6. 返回unused
注意

在步骤1中缺少绑定的 ECMAScript 代码示例是:

function f() { eval("var x; x = (delete x, 0);"); }

9.1.1.1.6 GetBindingValue ( N, S )

声明式环境记录 envRec的 GetBindingValue 具体方法接受参数N(一个字符串)和S(一个布尔值),并返回一个包含一个ECMAScript 语言值的正常完成记录或一个抛出完成记录。它返回其绑定标识符的值,其名称为N。如果绑定存在但未初始化,则抛出ReferenceError,无论S的值如何。调用时执行以下步骤:

  1. 断言envRecN的绑定。
  2. 如果envRecN的绑定是未初始化绑定,则抛出ReferenceError异常。
  3. 返回当前绑定到envRecN的值。

9.1.1.1.7 DeleteBinding ( N )

声明式环境记录 envRec的 DeleteBinding 具体方法接受参数N(一个字符串),并返回一个包含布尔值的正常完成记录。它只能删除已明确指定为可删除的绑定。调用时执行以下步骤:

  1. 断言envRecN的绑定。
  2. 如果envRecN的绑定不能被删除,则返回false
  3. envRec中移除N的绑定。
  4. 返回true

9.1.1.1.8 HasThisBinding ( )

声明式环境记录 envRec的 HasThisBinding 具体方法不接受任何参数并返回false。调用时执行以下步骤:

  1. 返回false
注意

常规声明式环境记录(即,不是函数环境记录模块环境记录)不提供this绑定。

9.1.1.1.9 HasSuperBinding ( )

声明式环境记录 envRec的 HasSuperBinding 具体方法不接受任何参数并返回false。调用时执行以下步骤:

  1. 返回false
注意

常规声明式环境记录(即,不是函数环境记录模块环境记录)不提供super绑定。

9.1.1.1.10 WithBaseObject ( )

声明式环境记录 envRec的 WithBaseObject 具体方法不接受任何参数并返回undefined。调用时执行以下步骤:

  1. 返回undefined

9.1.1.2 对象环境记录

每个对象环境记录都与一个称为绑定对象的对象相关联。对象环境记录绑定一组字符串标识符名称,这些名称直接对应于其绑定对象的属性名称。属性键不是标识符名称形式的字符串不包括在绑定标识符的集合中。无论其[[Enumerable]]属性的设置如何,自己的和继承的属性都包括在集合中。由于可以动态添加和删除属性,对象环境记录绑定的标识符集可能会因添加或删除属性的任何操作而改变。作为此类副作用创建的任何绑定都被视为可变绑定,即使相应属性的[[Writable]]属性为false。不可变绑定不存在于对象环境记录中。

with语句创建的对象环境记录(14.11)可以将其绑定对象作为隐式this值用于函数调用。此功能由布尔值[[IsWithEnvironment]]字段控制。

对象环境记录具有表17中列出的附加状态字段。

表17: 对象环境记录的附加字段
字段名称 含义
[[BindingObject]] 一个对象 环境记录的绑定对象。
[[IsWithEnvironment]] 一个布尔值 指示此环境记录是否为with语句创建。

对象环境记录的具体规范方法的行为由以下算法定义。

9.1.1.2.1 HasBinding ( N )

对象环境记录 envRec的 HasBinding 具体方法接受参数N(一个字符串),并返回一个包含布尔值的正常完成记录或一个抛出完成记录。它确定其关联的绑定对象是否具有名称为N的属性。调用时执行以下步骤:

  1. bindingObject成为envRec[[BindingObject]]
  2. foundBinding为? HasProperty(bindingObject, N)。
  3. 如果foundBindingfalse,返回false
  4. 如果envRec[[IsWithEnvironment]]false,返回true
  5. unscopables为? Get(bindingObject, @@unscopables)。
  6. 如果unscopables是一个对象,则
    1. blockedToBoolean(? Get(unscopables, N))。
    2. 如果blockedtrue,返回false
  7. 返回true

9.1.1.2.2 CreateMutableBinding ( N, D )

对象环境记录 envRec的 CreateMutableBinding 具体方法接受参数N(一个字符串)和D(一个布尔值),并返回一个包含 unused的正常完成记录或一个抛出完成记录。它在环境记录的关联绑定对象中创建一个名为N的属性,并将其初始化为undefined。如果Dtrue,新属性的[[Configurable]]属性设置为true;否则设置为false。调用时执行以下步骤:

  1. bindingObject成为envRec[[BindingObject]]
  2. 执行? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D })。
  3. 返回unused
注意

通常情况下,envRec不会有N的绑定,但如果有,DefinePropertyOrThrow的语义可能会导致替换或遮蔽现有绑定,或返回突然完成

9.1.1.2.3 CreateImmutableBinding ( N, S )

对象环境记录中从未使用过此规范。

9.1.1.2.4 InitializeBinding ( N, V )

对象环境记录 envRec的 InitializeBinding 具体方法接受参数N(一个字符串)和V(一个ECMAScript 语言值),并返回一个包含 unused的正常完成记录或一个抛出完成记录。它用于将名称为N的标识符的当前绑定值设置为V。调用时执行以下步骤:

  1. 执行? envRec.SetMutableBinding(N, V, false)。
  2. 返回unused
注意

在此规范中,所有对对象环境记录的 CreateMutableBinding 的使用都紧随其后调用 InitializeBinding 用于相同的名称。因此,此规范未明确跟踪对象环境记录中的绑定初始化状态。

9.1.1.2.5 SetMutableBinding ( N, V, S )

对象环境记录 envRec的 SetMutableBinding 具体方法接受参数N(一个字符串)、V(一个ECMAScript 语言值)和S(一个布尔值),并返回一个包含 unused的正常完成记录或一个抛出完成记录。它尝试将环境记录的关联绑定对象的名称为N的属性的值设置为V。通常情况下,该属性已经存在,但如果不存在或当前不可写,则错误处理由S决定。调用时执行以下步骤:

  1. bindingObject成为envRec[[BindingObject]]
  2. stillExists为? HasProperty(bindingObject, N)。
  3. 如果stillExistsfalseStrue,抛出ReferenceError异常。
  4. 执行? Set(bindingObject, N, V, S)。
  5. 返回unused

9.1.1.2.6 GetBindingValue ( N, S )

对象环境记录 envRec的 GetBindingValue 具体方法接受参数N(一个字符串)和S(一个布尔值),并返回一个包含一个ECMAScript 语言值的正常完成记录或一个抛出完成记录。它返回其关联绑定对象的名称为N的属性的值。该属性应该已经存在,但如果不存在,则结果取决于S。调用时执行以下步骤:

  1. bindingObject成为envRec[[BindingObject]]
  2. value为? HasProperty(bindingObject, N)。
  3. 如果valuefalse,则
    1. 如果Sfalse,返回undefined;否则抛出ReferenceError异常。
  4. 返回? Get(bindingObject, N)。

9.1.1.2.7 DeleteBinding ( N )

对象环境记录 envRec的 DeleteBinding 具体方法接受参数N(一个字符串),并返回一个包含布尔值的正常完成记录或一个抛出完成记录。它只能删除[[Configurable]]属性为true的环境对象的属性。调用时执行以下步骤:

  1. bindingObject成为envRec[[BindingObject]]
  2. 返回? bindingObject.[[Delete]](N)。

9.1.1.2.8 HasThisBinding ( )

对象环境记录 envRec的 HasThisBinding 具体方法不接受任何参数并返回false。调用时执行以下步骤:

  1. 返回false
注意

对象环境记录不提供this绑定。

9.1.1.2.9 HasSuperBinding ( )

对象环境记录 envRec的 HasSuperBinding 具体方法不接受任何参数并返回false。调用时执行以下步骤:

  1. 返回false
注意

对象环境记录不提供super绑定。

9.1.1.2.10 WithBaseObject ( )

对象环境记录 envRec的 WithBaseObject 具体方法不接受任何参数,并返回一个对象或undefined。调用时执行以下步骤:

  1. 如果envRec[[IsWithEnvironment]]true,返回envRec[[BindingObject]]
  2. 否则,返回undefined

9.1.1.3 函数环境记录

函数环境记录 是一种 声明性环境记录, 用于表示函数的顶级作用域,并且如果函数不是一个箭头函数,则提供一个 this绑定。如果函数不是一个箭头函数函数并引用 super,则其函数环境记录还包含用于在函数内部执行super方法调用的状态。

函数环境记录具有表18中列出的附加状态字段。

表18: 函数环境记录的附加字段
字段名称 含义
[[ThisValue]] 一个ECMAScript语言值 这是该函数调用中使用的this值。
[[ThisBindingStatus]] lexical, initializeduninitialized 如果值是lexical,则这是一个箭头函数,并且没有本地的this值。
[[FunctionObject]] 一个ECMAScript 函数对象 导致创建此环境记录函数对象
[[NewTarget]] 一个对象或undefined 如果此环境记录是由[[Construct]]内部方法创建的, 则[[NewTarget]][[Construct]]newTarget参数的值。 否则,其值为undefined

函数环境记录支持声明性环境记录中列出的所有方法, 并且除了HasThisBinding和HasSuperBinding方法之外,其它所有方法的规范相同。 此外,函数环境记录还支持表19中列出的方法:

表19: 函数环境记录的附加方法
方法 目的
BindThisValue(V) 设置[[ThisValue]]并记录它已被初始化。
GetThisBinding() 返回此环境记录this绑定的值。 如果this绑定尚未初始化,则抛出ReferenceError异常。
GetSuperBase() 返回在此环境记录中绑定的super属性访问的基础对象。 值undefined表示这些访问将产生运行时错误。

函数环境记录附加具体方法的行为由以下算法定义:

9.1.1.3.1 BindThisValue ( V )

函数环境记录BindThisValue具体方法接受参数V(一个ECMAScript语言值)并返回一个包含ECMAScript语言值的正常完成记录或一个抛出完成记录。 调用时执行以下步骤:

  1. 断言: envRec.[[ThisBindingStatus]]不是lexical
  2. 如果envRec.[[ThisBindingStatus]]initialized,抛出ReferenceError异常。
  3. envRec.[[ThisValue]]设置为V
  4. envRec.[[ThisBindingStatus]]设置为initialized
  5. 返回V

9.1.1.3.2 HasThisBinding ( )

函数环境记录HasThisBinding具体方法不接受任何参数并返回一个布尔值。 调用时执行以下步骤:

  1. 如果envRec.[[ThisBindingStatus]]lexical,返回false; 否则,返回true

9.1.1.3.3 HasSuperBinding ( )

函数环境记录HasSuperBinding具体方法不接受任何参数并返回一个布尔值。 调用时执行以下步骤:

  1. 如果envRec.[[ThisBindingStatus]]lexical,返回false
  2. 如果envRec.[[FunctionObject]].[[HomeObject]]undefined,返回false; 否则,返回true

9.1.1.3.4 GetThisBinding ( )

函数环境记录GetThisBinding具体方法不接受任何参数并返回一个包含ECMAScript语言值的正常完成记录或一个抛出完成记录。 调用时执行以下步骤:

  1. 断言: envRec.[[ThisBindingStatus]]不是lexical
  2. 如果envRec.[[ThisBindingStatus]]uninitialized,抛出ReferenceError异常。
  3. 返回envRec.[[ThisValue]]

9.1.1.3.5 GetSuperBase ( )

函数环境记录GetSuperBase具体方法不接受任何参数并返回一个包含一个对象、nullundefined的正常完成记录或一个抛出完成记录。 调用时执行以下步骤:

  1. home成为envRec.[[FunctionObject]].[[HomeObject]]
  2. 如果homeundefined,返回undefined
  3. 断言: home 是一个对象
  4. 返回? home.[[GetPrototypeOf]]()。

9.1.1.4 全局环境记录

全局环境记录用于表示所有在同一个领域中处理的ECMAScript 脚本元素共享的最外层作用域。全局环境记录提供内置全局变量的绑定(第19章)、全局对象的属性绑定, 以及所有在脚本中出现的顶级声明的绑定(8.2.98.2.11)。

全局环境记录在逻辑上是一个单一的记录,但它被指定为一个复合体,封装了一个对象环境记录和一个声明性环境记录对象环境记录的基础对象是相关领域记录全局对象。这个全局对象是全局环境记录的GetThisBinding具体方法返回的值。全局环境记录的对象环境记录组件包含所有内置全局变量(第19章)的绑定以及全局代码中包含的函数声明生成器声明异步函数声明异步生成器声明变量声明。全局代码中所有其他ECMAScript声明的绑定都包含在全局环境记录的声明性环境记录组件中。

属性可以直接在全局对象上创建。 因此,全局环境记录的对象环境记录组件可能同时包含由函数声明生成器声明异步函数声明异步生成器声明变量声明显式创建的绑定以及作为全局对象属性隐式创建的绑定。 为了确定哪些绑定是通过声明显式创建的,全局环境记录维护一个使用其CreateGlobalVarBinding和CreateGlobalFunctionBinding具体方法绑定的名称列表。

全局环境记录具有表20中列出的附加字段和表21中列出的附加方法。

表20: 全局环境记录的附加字段
字段名称 含义
[[ObjectRecord]] 一个对象环境记录 绑定对象是全局对象。它包含全局内置绑定以及全局代码中的函数声明生成器声明异步函数声明异步生成器声明、 和变量声明绑定,针对相关的领域
[[GlobalThisValue]] 一个对象 全局作用域中this返回的值。宿主可以提供任何ECMAScript对象值。
[[DeclarativeRecord]] 一个声明性环境记录 包含所有在相关领域代码中的全局代码声明的绑定,除了函数声明生成器声明异步函数声明异步生成器声明、 和变量声明绑定。
[[VarNames]] 一个字符串列表 在相关领域代码的全局代码中,函数声明生成器声明异步函数声明异步生成器声明、 和变量声明的绑定名称。
表21: 全局环境记录的附加方法
方法 目的
GetThisBinding() 返回此环境记录this绑定的值。
HasVarDeclaration (N) 确定参数标识符是否在此环境记录中具有通过变量声明函数声明生成器声明异步函数声明、 或异步生成器声明创建的绑定。
HasLexicalDeclaration (N) 确定参数标识符是否在此环境记录中具有通过词法声明(如词法声明类声明)创建的绑定。
HasRestrictedGlobalProperty (N) 确定参数是否为全局对象属性的名称,该属性不得被全局词法绑定遮蔽。
CanDeclareGlobalVar (N) 确定是否可以成功调用相应的CreateGlobalVarBinding方法,并为相同的参数N声明全局变量。
CanDeclareGlobalFunction (N) 确定是否可以成功调用相应的CreateGlobalFunctionBinding方法,并为相同的参数N声明全局函数。
CreateGlobalVarBinding(N, D) 用于在[[ObjectRecord]]组件中创建并初始化一个全局var绑定, 该绑定的初始值为undefined。绑定将是可变绑定。 相应的全局对象属性将具有适合var的属性值。 字符串值N是绑定的名称。如果Dtrue,则绑定可以被删除。 在逻辑上等同于CreateMutableBinding后跟SetMutableBinding,但它允许对var声明进行特殊处理。
CreateGlobalFunctionBinding(N, V, D) [[ObjectRecord]]组件中创建并初始化一个全局function绑定。 绑定将是可变绑定。相应的全局对象属性将具有适合function的属性值。 字符串值N是绑定的名称。V是初始化值。 如果布尔参数Dtrue,则绑定可以被删除。 在逻辑上等同于CreateMutableBinding后跟SetMutableBinding,但它允许对函数声明进行特殊处理。

具体规范方法的行为定义如下算法。

9.1.1.4.1 HasBinding ( N )

全局环境记录envRec的HasBinding具体方法接受参数N(字符串),返回一个正常完成记录,包含一个布尔值或一个抛出完成记录。它确定参数标识符是否被记录绑定。调用时执行以下步骤:

  1. DclRecenvRec[[DeclarativeRecord]]
  2. 如果! DclRec.HasBinding(N)为true,返回true
  3. ObjRecenvRec[[ObjectRecord]]
  4. 返回? ObjRec.HasBinding(N)。

9.1.1.4.2 CreateMutableBinding ( N, D )

全局环境记录envRec的CreateMutableBinding具体方法接受参数N(字符串)和D(布尔值),返回一个正常完成记录,包含未使用或一个抛出完成记录。它创建一个新的未初始化的可变绑定,绑定在相关的声明记录中。声明记录中不能已经存在N的绑定。如果Dtrue,新的绑定标记为可删除。调用时执行以下步骤:

  1. DclRecenvRec[[DeclarativeRecord]]
  2. 如果! DclRec.HasBinding(N)为true,抛出类型错误异常。
  3. 返回 ! DclRec.CreateMutableBinding(N, D)。

9.1.1.4.3 CreateImmutableBinding ( N, S )

全局环境记录envRec的CreateImmutableBinding具体方法接受参数N(字符串)和S(布尔值),返回一个正常完成记录,包含未使用或一个抛出完成记录。它创建一个新的未初始化的不可变绑定。该环境记录中不能已经存在N的绑定。如果Strue,新的绑定标记为严格绑定。调用时执行以下步骤:

  1. DclRecenvRec[[DeclarativeRecord]]
  2. 如果! DclRec.HasBinding(N)为true,抛出类型错误异常。
  3. 返回 ! DclRec.CreateImmutableBinding(N, S)。

9.1.1.4.4 InitializeBinding ( N, V )

全局环境记录envRec的InitializeBinding具体方法接受参数N(字符串)和VECMAScript语言值),返回一个正常完成记录,包含未使用或一个抛出完成记录。它用于将标识符的当前绑定的值设置为V。必须已经存在一个未初始化的N绑定。调用时执行以下步骤:

  1. DclRecenvRec[[DeclarativeRecord]]
  2. 如果! DclRec.HasBinding(N)为true,则
    1. 返回 ! DclRec.InitializeBinding(N, V)。
  3. 断言:如果绑定存在,它必须在对象环境记录中。
  4. ObjRecenvRec[[ObjectRecord]]
  5. 返回? ObjRec.InitializeBinding(N, V)。

9.1.1.4.5 SetMutableBinding ( N, V, S )

全局环境记录envRec的SetMutableBinding具体方法接受参数N(字符串)、VECMAScript语言值)和S(布尔值),返回一个正常完成记录,包含未使用或一个抛出完成记录。它尝试将标识符的当前绑定的值更改为V。如果绑定是不可变的,并且Strue,则抛出类型错误。通常已经存在名为N的属性,但如果不存在或当前不可写,错误处理由S决定。调用时执行以下步骤:

  1. DclRecenvRec[[DeclarativeRecord]]
  2. 如果! DclRec.HasBinding(N)为true,则
    1. 返回 ? DclRec.SetMutableBinding(N, V, S)。
  3. ObjRecenvRec[[ObjectRecord]]
  4. 返回? ObjRec.SetMutableBinding(N, V, S)。

9.1.1.4.6 GetBindingValue ( N, S )

全局环境记录envRec的GetBindingValue具体方法接受参数N(字符串)和S(布尔值),返回一个正常完成记录,包含一个ECMAScript语言值或一个抛出完成记录。它返回标识符N的绑定值。如果绑定是未初始化的,则抛出引用错误异常。通常已经存在名为N的属性,但如果不存在或当前不可写,错误处理由S决定。调用时执行以下步骤:

  1. DclRecenvRec[[DeclarativeRecord]]
  2. 如果! DclRec.HasBinding(N)为true,则
    1. 返回 ? DclRec.GetBindingValue(N, S)。
  3. ObjRecenvRec[[ObjectRecord]]
  4. 返回? ObjRec.GetBindingValue(N, S)。

9.1.1.4.7 DeleteBinding ( N )

全局环境记录envRec的DeleteBinding具体方法接受参数N(字符串),返回一个正常完成记录,包含一个布尔值或一个抛出完成记录。它只能删除已明确指定为可删除的绑定。调用时执行以下步骤:

  1. DclRecenvRec[[DeclarativeRecord]]
  2. 如果! DclRec.HasBinding(N)为true,则
    1. 返回 ! DclRec.DeleteBinding(N)。
  3. ObjRecenvRec[[ObjectRecord]]
  4. globalObjectObjRec[[BindingObject]]
  5. existingProp为? HasOwnProperty(globalObject, N)。
  6. 如果existingProptrue,则
    1. status为? ObjRec.DeleteBinding(N)。
    2. 如果statustrue,并且envRec[[VarNames]]包含N,则
      1. envRec[[VarNames]]中删除N
    3. 返回status
  7. 返回true

9.1.1.4.8 HasThisBinding ( )

全局环境记录envRec的HasThisBinding具体方法不接受参数,返回true。调用时执行以下步骤:

  1. 返回true

全局环境记录总是提供this绑定。

9.1.1.4.9 HasSuperBinding ( )

全局环境记录envRec的HasSuperBinding具体方法不接受参数,返回false。调用时执行以下步骤:

  1. 返回false

全局环境记录不提供super绑定。

9.1.1.4.10 WithBaseObject ( )

全局环境记录envRec的WithBaseObject具体方法不接受参数,返回undefined。调用时执行以下步骤:

  1. 返回undefined

9.1.1.4.11 GetThisBinding ( )

全局环境记录envRec的GetThisBinding具体方法不接受参数,返回一个正常完成记录,包含一个对象。调用时执行以下步骤:

  1. 返回envRec[[GlobalThisValue]]

9.1.1.4.12 HasVarDeclaration ( N )

全局环境记录envRec的HasVarDeclaration具体方法接受参数N(字符串),返回一个布尔值。它确定参数标识符是否在此记录中具有通过变量语句函数声明创建的绑定。调用时执行以下步骤:

  1. varDeclaredNamesenvRec[[VarNames]]
  2. 如果varDeclaredNames包含N,返回 true
  3. 返回false

9.1.1.4.13 HasLexicalDeclaration ( N )

全局环境记录envRec的HasLexicalDeclaration具体方法接受参数N(字符串),返回一个布尔值。它确定参数标识符是否在此记录中具有通过词法声明(如词法声明类声明)创建的绑定。调用时执行以下步骤:

  1. DclRecenvRec[[DeclarativeRecord]]
  2. 返回! DclRec.HasBinding(N)。

9.1.1.4.14 HasRestrictedGlobalProperty ( N )

全局环境记录envRec的HasRestrictedGlobalProperty具体方法接受参数N(字符串),返回一个正常完成记录,包含一个布尔值或一个抛出完成记录。它确定参数标识符是否为全局对象属性的名称,该属性不得被全局词法绑定遮蔽。调用时执行以下步骤:

  1. ObjRecenvRec[[ObjectRecord]]
  2. globalObjectObjRec[[BindingObject]]
  3. existingProp为? globalObject.[[GetOwnProperty]](N)。
  4. 如果existingProp未定义, 返回false
  5. 如果existingProp[[Configurable]]true,返回false
  6. 返回true

全局对象上可能存在直接创建的属性,而不是通过var或函数声明创建的。 不得创建具有与全局对象的不可配置属性相同名称的全局词法绑定。全局属性"undefined"就是一个例子。

9.1.1.4.15 CanDeclareGlobalVar ( N )

全局环境记录envRec的CanDeclareGlobalVar具体方法接受参数N(字符串),返回一个正常完成记录,包含一个布尔值或一个抛出完成记录。它确定是否可以成功调用相应的CreateGlobalVarBinding方法,并为相同的参数N声明全局变量。允许冗余的var声明和已存在的全局对象属性的var声明。调用时执行以下步骤:

  1. ObjRecenvRec[[ObjectRecord]]
  2. globalObjectObjRec[[BindingObject]]
  3. hasProperty为? HasOwnProperty(globalObject, N)。
  4. 如果hasPropertytrue,返回 true
  5. 返回? IsExtensible(globalObject)。

9.1.1.4.16 CanDeclareGlobalFunction ( N )

全局环境记录envRec的CanDeclareGlobalFunction具体方法接受参数N(字符串),返回一个正常完成记录,包含一个布尔值或一个抛出完成记录。它确定是否可以成功调用相应的CreateGlobalFunctionBinding方法,并为相同的参数N声明全局函数。调用时执行以下步骤:

  1. ObjRecenvRec[[ObjectRecord]]
  2. globalObjectObjRec[[BindingObject]]
  3. existingProp为? globalObject.[[GetOwnProperty]](N)。
  4. 如果existingProp未定义, 返回? IsExtensible(globalObject)。
  5. 如果existingProp[[Configurable]]true,返回true
  6. 如果IsDataDescriptor(existingProp) 为true,且existingProp具有属性值{ [[Writable]]: true, [[Enumerable]]: true },返回true
  7. 返回false

9.1.1.4.17 CreateGlobalVarBinding ( N, D )

全局环境记录envRec的CreateGlobalVarBinding具体方法接受参数N(字符串)和D(布尔值),返回一个正常完成记录,包含未使用或一个抛出完成记录。它在相关的对象环境记录中创建并初始化一个可变绑定,并在相关的[[VarNames]]中记录绑定名称列表。如果绑定已经存在,它将被重用并假定为已初始化。调用时执行以下步骤:

  1. ObjRecenvRec[[ObjectRecord]]
  2. globalObjectObjRec[[BindingObject]]
  3. hasProperty为? HasOwnProperty(globalObject, N)。
  4. extensible为? IsExtensible(globalObject)。
  5. 如果hasPropertyfalse并且extensibletrue,则
    1. 执行? ObjRec.CreateMutableBinding(N, D)。
    2. 执行? ObjRec.InitializeBinding(N, 未定义)。
  6. 如果envRec[[VarNames]] 不包含N,则
    1. N追加到envRec[[VarNames]]中。
  7. 返回未使用

9.1.1.4.18 CreateGlobalFunctionBinding ( N, V, D )

全局环境记录envRec的CreateGlobalFunctionBinding具体方法接受参数N(字符串)、VECMAScript语言值)和D(布尔值),返回一个正常完成记录,包含未使用或一个抛出完成记录。它在相关的对象环境记录中创建并初始化一个可变绑定,并在相关的[[VarNames]]中记录绑定名称列表。如果绑定已经存在,它将被替换。调用时执行以下步骤:

  1. ObjRecenvRec[[ObjectRecord]]
  2. globalObjectObjRec[[BindingObject]]
  3. existingProp为? globalObject.[[GetOwnProperty]](N)。
  4. 如果existingProp未定义existingProp[[Configurable]]true,则
    1. desc为属性描述符{ [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }.
  5. 否则,
    1. desc为属性描述符{ [[Value]]: V }。
  6. 执行? DefinePropertyOrThrow(globalObject, N, desc)。
  7. 执行 ? Set(globalObject, N, V, false)。
  8. 如果envRec[[VarNames]] 不包含N,则
    1. N追加到envRec[[VarNames]]中。
  9. 返回未使用

全局函数声明始终表示为全局对象的自有属性。 如果可能,将重新配置现有的自有属性以具有一组标准的属性值。 第7步等效于调用InitializeBinding具体方法,如果globalObject是代理,则会产生相同的代理陷阱调用顺序。

9.1.1.5 模块环境记录

模块环境记录 是一种 声明环境记录,用于表示 ECMAScript 模块 的外部作用域。除了常规的可变和不可变绑定外,模块环境记录还提供了不可变的导入绑定,这些绑定提供了对存在于另一个 环境记录 中目标绑定的间接访问。

模块环境记录支持所有在 声明环境记录中列出的 表 16 的方法,并共享这些方法的相同规范,除了 GetBindingValue、DeleteBinding、HasThisBinding 和 GetThisBinding 外。此外,模块环境记录还支持在 表 22 中列出的方法:

表 22: 模块环境记录的附加方法
方法 目的
CreateImportBinding(N, M, N2) 在一个模块环境记录中创建一个不可变的间接绑定。字符串值 N 是绑定名称的文本。M 是一个 模块记录N2 是存在于 M模块环境记录 中的一个绑定。
GetThisBinding() 返回该环境记录的 this 绑定的值。

模块环境记录的附加具体规范方法的行为由以下算法定义:

9.1.1.5.1 GetBindingValue ( N, S )

模块环境记录的 GetBindingValue 具体方法 envRec 接受参数 N(字符串)和 S(布尔值),返回一个包含 ECMAScript 语言值的正常完成记录或抛出完成记录。它返回其绑定标识符 N 的值。但是,如果绑定是间接绑定,则返回目标绑定的值。如果绑定存在但未初始化,则抛出 ReferenceError。调用时执行以下步骤:

  1. 断言: Strue
  2. 断言: envRec 有一个绑定 N
  3. 如果 N 的绑定是间接绑定,那么:
    1. MN2 为创建该 N 绑定时提供的间接值。
    2. targetEnvM[[Environment]]
    3. 如果 targetEnvempty,则抛出 ReferenceError
    4. 返回 ? targetEnv.GetBindingValue(N2, true)。
  4. 如果 envRecN 的绑定是未初始化的绑定,则抛出 ReferenceError
  5. 返回当前绑定在 envRec 中的 N 的值。

S 将始终为 true,因为模块始终是严格模式代码。

9.1.1.5.2 DeleteBinding ( N )

模块环境记录的 DeleteBinding 具体方法在本规范中从未使用。

模块环境记录仅在严格代码中使用,并且在严格代码中,早期错误规则防止 delete 操作符应用于将解析为模块环境记录绑定的引用记录。详见13.5.1.1

9.1.1.5.3 HasThisBinding ( )

模块环境记录的 HasThisBinding 具体方法 envRec 不接受任何参数并返回 true。调用时执行以下步骤:

  1. 返回 true

模块环境记录始终提供 this 绑定。

9.1.1.5.4 GetThisBinding ( )

模块环境记录的 GetThisBinding 具体方法 envRec 不接受任何参数并返回 undefined。调用时执行以下步骤:

  1. 返回 undefined

9.1.1.5.5 CreateImportBinding ( N, M, N2 )

模块环境记录的 CreateImportBinding 具体方法 envRec 接受参数 N(字符串)、M模块记录)和 N2(字符串),并返回 未使用。它为名称 N 创建一个新的初始化的不可变间接绑定。在此环境记录中不得已有名称为 N 的绑定。N2M 的模块环境记录中存在的一个绑定的名称。对新绑定值的访问将间接访问目标绑定的绑定值。调用时执行以下步骤:

  1. 断言: envRec 不得已有名称为 N 的绑定。
  2. 断言: 当 M[[Environment]] 实例化时,它将具有名称为 N2 的直接绑定。
  3. envRec 中创建一个不可变的间接绑定,引用 MN2 作为其目标绑定,并记录该绑定已初始化。
  4. 返回 未使用

9.1.2 环境记录操作

本规范使用以下 抽象操作 来对 环境记录 进行操作:

9.1.2.1 GetIdentifierReference ( env, name, strict )

抽象操作 GetIdentifierReference 接受参数 env(一个 环境记录null)、name(字符串)和 strict(布尔值),返回一个包含 引用记录 的正常完成记录或抛出完成记录。调用时执行以下步骤:

  1. 如果 envnull,则
    1. 返回 引用记录 { [[Base]]: unresolvable, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty }。
  2. exists 为 ? env.HasBinding(name)。
  3. 如果 existstrue,则
    1. 返回 引用记录 { [[Base]]: env, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty }。
  4. 否则,
    1. outerenv.[[OuterEnv]]
    2. 返回 ? GetIdentifierReference(outer, name, strict)。

9.1.2.2 NewDeclarativeEnvironment ( E )

抽象操作 NewDeclarativeEnvironment 接受参数 E(一个 环境记录null),返回一个 声明环境记录。调用时执行以下步骤:

  1. env 为一个新的 声明环境记录,其中不包含任何绑定。
  2. env.[[OuterEnv]] 设置为 E
  3. 返回 env

9.1.2.3 NewObjectEnvironment ( O, W, E )

抽象操作 NewObjectEnvironment 接受参数 O(一个对象)、W(布尔值)和 E(一个 环境记录null),返回一个 对象环境记录。调用时执行以下步骤:

  1. env 为一个新的 对象环境记录
  2. env.[[BindingObject]] 设置为 O
  3. env.[[IsWithEnvironment]] 设置为 W
  4. env.[[OuterEnv]] 设置为 E
  5. 返回 env

9.1.2.4 NewFunctionEnvironment ( F, newTarget )

抽象操作 NewFunctionEnvironment 接受参数 F(一个 ECMAScript 函数对象)和 newTarget(一个对象或 undefined),返回一个 函数环境记录。调用时执行以下步骤:

  1. env 为一个新的 函数环境记录,其中不包含任何绑定。
  2. env.[[FunctionObject]] 设置为 F
  3. 如果 F.[[ThisMode]]lexical,将 env.[[ThisBindingStatus]] 设置为 lexical
  4. 否则,将 env.[[ThisBindingStatus]] 设置为 uninitialized
  5. env.[[NewTarget]] 设置为 newTarget
  6. env.[[OuterEnv]] 设置为 F.[[Environment]]
  7. 返回 env

9.1.2.5 NewGlobalEnvironment ( G, thisValue )

抽象操作 NewGlobalEnvironment 接受参数 G(一个对象)和 thisValue(一个对象),返回一个 全局环境记录。调用时执行以下步骤:

  1. objRecNewObjectEnvironment(G, false, null)。
  2. dclRecNewDeclarativeEnvironment(null)。
  3. env 为一个新的 全局环境记录
  4. env.[[ObjectRecord]] 设置为 objRec
  5. env.[[GlobalThisValue]] 设置为 thisValue
  6. env.[[DeclarativeRecord]] 设置为 dclRec
  7. env.[[VarNames]] 设置为一个新的空 列表
  8. env.[[OuterEnv]] 设置为 null
  9. 返回 env

9.1.2.6 NewModuleEnvironment ( E )

抽象操作 NewModuleEnvironment 接受参数 E(一个 环境记录),返回一个 模块环境记录。调用时执行以下步骤:

  1. env 为一个新的 模块环境记录,其中不包含任何绑定。
  2. env.[[OuterEnv]] 设置为 E
  3. 返回 env

9.2 私有环境记录

私有环境记录 是一种用于根据 ECMAScript 代码中的 类声明类表达式 的词法嵌套结构跟踪 私有名称 的规范机制。它们类似于但不同于 环境记录。每个 私有环境记录 都与一个 类声明类表达式 相关联。每次评估这样的类时,都会创建一个新的 私有环境记录 来记录该类声明的 私有名称

每个 私有环境记录 都具有 表 23 中定义的字段。

表 23: 私有环境记录 字段
字段名 值类型 含义
[[OuterPrivateEnvironment]] 一个 私有环境记录null 最近的包含类的 私有环境记录。如果与此 私有环境记录 关联的类不包含在任何其他类中,则为 null
[[Names]] 一个 列表,包含 私有名称 该类声明的 私有名称

9.2.1 私有环境记录操作

本规范使用以下 抽象操作 来对 私有环境记录 进行操作:

9.2.1.1 NewPrivateEnvironment ( outerPrivEnv )

抽象操作 NewPrivateEnvironment 接受参数 outerPrivEnv(一个 私有环境记录null),返回一个 私有环境记录。调用时执行以下步骤:

  1. names 为一个新的空 列表
  2. 返回 私有环境记录 { [[OuterPrivateEnvironment]]: outerPrivEnv, [[Names]]: names }。

9.2.1.2 ResolvePrivateIdentifier ( privEnv, identifier )

抽象操作 ResolvePrivateIdentifier 接受参数 privEnv(一个 私有环境记录)和 identifier(字符串),返回一个 私有名称。调用时执行以下步骤:

  1. namesprivEnv.[[Names]]
  2. 对于 names 中的每个 私有名称 pn, 执行以下步骤:
    1. 如果 pn.[[Description]]identifier,则:
      1. 返回 pn
  3. outerPrivEnvprivEnv.[[OuterPrivateEnvironment]]
  4. 断言outerPrivEnv 不为 null
  5. 返回 ResolvePrivateIdentifier( outerPrivEnv, identifier)。

9.3 范围(Realms)

在评估之前,所有 ECMAScript 代码都必须与一个 范围 相关联。从概念上讲,一个 范围 由一组内置对象、一个 ECMAScript 全局环境、在该全局环境范围内加载的所有 ECMAScript 代码,以及其他相关状态和资源组成。

本规范中以 范围记录 表示 范围,其字段在 表 24 中指定:

表 24:范围记录 字段
字段名称 含义
[[AgentSignifier]] 一个 代理标识符 拥有此 范围代理
[[Intrinsics]] 一个 记录,其字段名称是内置键,其值是对象 与此 范围 相关联的代码使用的内置值
[[GlobalObject]] 一个对象或 undefined 全局对象 对于此 范围
[[GlobalEnv]] 一个 全局环境记录 范围 的全局环境
[[TemplateMap]] 一个 列表,包含字段 [[Site]](一个 模板字面量 解析节点)和 [[Array]](一个数组)

模板对象在每个 范围 中分别进行规范化,使用其 范围记录[[TemplateMap]]。每个 [[Site]] 值是一个 解析节点,即一个 模板字面量。关联的 [[Array]] 值是传递给标签函数的相应模板对象。

注 1
一旦 解析节点 变得不可达,对应的 [[Array]] 也会变得不可达,如果实现从 [[TemplateMap]] 列表中删除该对,这将是不可观察的。
[[LoadedModules]] 一个 列表,包含字段 [[Specifier]](一个字符串)和 [[Module]](一个 模块记录

从此 范围 导入的说明符字符串到已解析的 模块记录 的映射。该列表不包含两个具有相同 [[Specifier]] 的不同 记录

注 2
正如在 HostLoadImportedModule16.2.1.8 注 1)中所述, [[LoadedModules]]范围记录 中仅在没有 活动脚本或模块 的上下文中运行 import() 表达式时使用。
[[HostDefined]] 任何(默认值为 undefined 主机 保留的字段,用于将其他信息与 范围记录 关联。

9.3.1 创建范围(CreateRealm) ( )

抽象操作 CreateRealm 不接受任何参数并返回一个 范围记录。调用时执行以下步骤:

  1. realmRec 为一个新的 范围记录
  2. 执行 CreateIntrinsics(realmRec)。
  3. realmRec.[[AgentSignifier]] 设置为 AgentSignifier()。
  4. realmRec.[[GlobalObject]] 设置为 undefined
  5. realmRec.[[GlobalEnv]] 设置为 undefined
  6. realmRec.[[TemplateMap]] 设置为一个新的空 列表
  7. 返回 realmRec

9.3.2 创建内置对象(CreateIntrinsics) ( realmRec )

抽象操作 CreateIntrinsics 接受参数 realmRec(一个 范围记录)并返回 unused。调用时执行以下步骤:

  1. realmRec.[[Intrinsics]] 设置为一个新的 记录
  2. 使用 表 6 中列出的值设置 realmRec.[[Intrinsics]] 的字段。这些字段名称是表的第一列中列出的名称。每个字段的值是一个新的对象值,按照规范中的定义完全递归地填充属性值。这些对象的创建顺序必须避免对尚未创建的对象的依赖。
  3. 执行 AddRestrictedFunctionProperties(realmRec.[[Intrinsics]].[[%Function.prototype%]], realmRec)。
  4. 返回 unused

9.3.3 设置范围全局对象(SetRealmGlobalObject) ( realmRec, globalObj, thisValue )

抽象操作 SetRealmGlobalObject 接受参数 realmRec(一个 范围记录)、globalObj(一个对象或 undefined),以及 thisValue(一个对象或 undefined),并返回 unused。调用时执行以下步骤:

  1. 如果 globalObjundefined,则:
    1. intrinsicsrealmRec.[[Intrinsics]]
    2. globalObj 设置为 OrdinaryObjectCreate(intrinsics.[[%Object.prototype%]])。
  2. 断言globalObj一个对象
  3. 如果 thisValueundefined,则将 thisValue 设置为 globalObj
  4. realmRec.[[GlobalObject]] 设置为 globalObj
  5. newGlobalEnvNewGlobalEnvironment(globalObj, thisValue)。
  6. realmRec.[[GlobalEnv]] 设置为 newGlobalEnv
  7. 返回 unused

9.3.4 设置默认全局绑定(SetDefaultGlobalBindings) ( realmRec )

抽象操作 SetDefaultGlobalBindings 接受参数 realmRec(一个 范围记录)并返回一个 正常完成的对象 或 一个 抛出完成。调用时执行以下步骤:

  1. globalrealmRec.[[GlobalObject]]
  2. 对于在 第 19 章 中指定的全局对象的每个属性,执行:
    1. name 为属性名称的字符串值。
    2. desc 为该属性的完全填充的数据 属性描述符,包含该属性的指定属性。对于 第 19.2 章第 19.3 章第 19.4 章 中列出的属性,其 [[Value]] 属性的值是对应的内置对象。
    3. 执行 ? DefinePropertyOrThrow(global, name, desc)。
  3. 返回 global

9.4 执行上下文(Execution Contexts)

执行上下文 是一个规范设备,用于跟踪 ECMAScript 实现对代码的运行时评估。在任何时候,每个 代理 至多只有一个正在实际执行代码的执行上下文。这被称为该 代理正在运行的执行上下文。在此规范中的所有对 正在运行的执行上下文 的引用都指的是 围绕的代理正在运行的执行上下文

执行上下文堆栈 用于跟踪执行上下文。正在运行的执行上下文 始终是该堆栈的顶部元素。每当控制从当前 正在运行的执行上下文 关联的可执行代码转移到与该执行上下文无关的可执行代码时,都会创建一个新的执行上下文。新创建的执行上下文会被推送到堆栈顶部,成为 正在运行的执行上下文

执行上下文包含所有跟踪其关联代码执行进度的必要实现特定状态。每个执行上下文至少有 表 25 中列出的状态组件。

表 25: 所有执行上下文的状态组件
组件 目的
代码评估状态 执行、暂停和恢复与此 执行上下文 关联的代码所需的任何状态。
函数 如果此 执行上下文 正在评估 函数对象 的代码,则此组件的值为该 函数对象。如果上下文正在评估 脚本模块 的代码,则值为 null
范围 关联代码访问 ECMAScript 资源的 范围记录
脚本或模块 关联代码来源的 模块记录脚本记录。如果没有起源脚本或模块,如在 InitializeHostDefinedRealm 中创建的原始 执行上下文 的情况,则值为 null

评估 代码时 正在运行的执行上下文 可能会在此规范中定义的各个点暂停。一旦 正在运行的执行上下文 被暂停,不同的执行上下文可能成为 正在运行的执行上下文 并开始评估其代码。稍后,暂停的执行上下文可能再次成为 正在运行的执行上下文 并在先前暂停的点继续评估其代码。正在运行的执行上下文 状态在执行上下文之间的转换通常以堆栈样式的后进先出方式进行。然而,一些 ECMAScript 特性需要 正在运行的执行上下文 的非 LIFO 转换。

范围 组件的值也被称为 当前范围记录正在运行的执行上下文 的函数组件的值也被称为 活动函数对象

ECMAScript 代码执行上下文 具有 表 26 中列出的附加状态组件。

表 26: ECMAScript 代码执行上下文的附加状态组件
组件 目的
词法环境 标识用于解析此 执行上下文 内代码所做的标识符引用的 环境记录
变量环境 标识在此 执行上下文 中由 变量声明 创建绑定的 环境记录
私有环境 标识由最近包含类中的 类元素 创建的 私有名称私有环境记录。如果没有包含类,则为 null

执行上下文的词法环境和变量环境组件始终是 环境记录

表示生成器评估的执行上下文具有 表 27 中列出的附加状态组件。

表 27: 生成器执行上下文的附加状态组件
组件 目的
生成器 执行上下文 正在评估的生成器。

在大多数情况下,仅由此规范中的算法直接操作 正在运行的执行上下文执行上下文堆栈 的顶部)。因此,当未注明时使用术语“词法环境”和“变量环境”,它们是指 正在运行的执行上下文 的这些组件。

执行上下文纯粹是一个规范机制,不需要对应于 ECMAScript 实现的任何特定制品。ECMAScript 代码不可能直接访问或观察到执行上下文。

9.4.1 GetActiveScriptOrModule ( )

抽象操作 GetActiveScriptOrModule 不接受参数,并返回 脚本记录模块记录null。它用于基于 正在运行的执行上下文 确定正在运行的脚本或模块。调用时执行以下步骤:

  1. 如果 执行上下文堆栈 为空,则返回 null
  2. ec执行上下文堆栈 中最顶部的 执行上下文,其 ScriptOrModule 组件不为 null
  3. 如果不存在这样的 执行上下文,则返回 null。否则,返回 ec 的 ScriptOrModule。

9.4.2 ResolveBinding ( name [ , env ] )

抽象操作 ResolveBinding 接受参数 name(一个字符串)和可选参数 env(一个 环境记录undefined),并返回 正常完成记录,包含一个 引用记录 或一个 抛出完成记录。它用于确定 name 的绑定。env 可以用于显式提供要搜索绑定的 环境记录。调用时执行以下步骤:

  1. 如果未提供 envenvundefined,则
    1. env 设置为 正在运行的执行上下文 的词法环境。
  2. 断言env 是一个 环境记录
  3. 如果正在评估的语法生成的 源文本匹配 包含在 严格模式代码 中,则将 strict 设置为 true;否则将 strict 设置为 false
  4. 返回 ? GetIdentifierReference(env, name, strict)。
注意

ResolveBinding 的结果始终是一个 引用记录,其 [[ReferencedName]] 字段是 name

9.4.3 GetThisEnvironment ( )

抽象操作 GetThisEnvironment 不接受参数,并返回一个 环境记录。它找到当前提供 this 绑定的 环境记录。调用时执行以下步骤:

  1. env 设置为 正在运行的执行上下文 的词法环境。
  2. 重复以下步骤,直到条件不成立为止:
    1. existsenv.HasThisBinding()。
    2. 如果 existstrue,则返回 env
    3. outer 设置为 env.[[OuterEnv]]
    4. 断言outer 不是 null
    5. env 设置为 outer
注意

步骤 2 中的循环将始终终止,因为环境列表总是以具有 this 绑定的全局环境结束。

9.4.4 ResolveThisBinding ( )

抽象操作 ResolveThisBinding 不接受参数,并返回 正常完成记录,包含一个 ECMAScript 语言值 或一个 抛出完成记录。它使用 正在运行的执行上下文 的词法环境确定 this 的绑定。调用时执行以下步骤:

  1. envRecGetThisEnvironment()。
  2. 返回 ? envRec.GetThisBinding()。

9.4.5 GetNewTarget ( )

抽象操作 GetNewTarget 不接受参数,并返回一个对象或 undefined。它使用 正在运行的执行上下文 的词法环境确定 NewTarget 值。调用时执行以下步骤:

  1. envRecGetThisEnvironment()。
  2. 断言envRec 具有 [[NewTarget]] 字段。
  3. 返回 envRec.[[NewTarget]]

9.4.6 GetGlobalObject ( )

抽象操作 GetGlobalObject 不接受参数并返回一个对象。它返回由当前 正在运行的执行上下文 使用的 全局对象。调用时执行以下步骤:

  1. currentRealm当前范围记录
  2. 返回 currentRealm.[[GlobalObject]]

9.5 Jobs and Host Operations to Enqueue Jobs

作业是一个无参数的抽象闭包,在没有其他 ECMAScript 计算正在进行时启动 ECMAScript 计算。

作业由 ECMAScript 宿主环境在特定的代理中调度执行。本规范描述了宿主挂钩HostEnqueueGenericJobHostEnqueueFinalizationRegistryCleanupJobHostEnqueuePromiseJobHostEnqueueTimeoutJob来调度作业。这个规范中的宿主挂钩按调度作业时附加的约束进行组织。宿主可以定义其他抽象操作来调度作业。这些操作接受一个作业抽象闭包和一个范围(一个范围记录null)作为参数。如果提供了范围记录,这些操作会在提供的范围中调度作业,以由拥有范围代理在将来的某个时间执行。如果提供的是null,则该作业不会执行 ECMAScript 代码。其实现必须符合以下要求:

注意 1
宿主环境不需要 以统一的方式对待作业的调度。例如,网络浏览器和 Node.js 将 Promise 处理作业视为比其他工作优先级更高;未来的功能可能会添加作业,这些作业不会被视为如此高的优先级。

在任何特定时间,如果以下所有条件都为真,则scriptOrModule(一个脚本记录、一个模块记录null)是活动脚本或模块

在任何特定时间,如果以下所有条件都为真,则执行准备好评估 ECMAScript 代码

注意 2

宿主环境可以通过将执行上下文推入执行上下文堆栈来准备评估代码。具体步骤是实现定义的

选择范围的具体方式取决于宿主环境。这个初始执行上下文范围仅在调用任何回调函数之前使用。当与作业相关的回调函数(例如 Promise 处理程序)被调用时,调用会推入自己的执行上下文范围

特定种类的作业有额外的符合性要求。

9.5.1 作业回调记录

作业回调记录是一个记录值,用于存储一个函数对象和一个宿主定义的值。通过宿主排队的作业调用的函数对象可以具有额外的宿主定义上下文。为了传播状态,作业的抽象闭包不应该直接捕获并调用函数对象。相反,使用HostMakeJobCallbackHostCallJobCallback

注意

WHATWG HTML 规范(https://html.spec.whatwg.org/)例如,使用宿主定义的值传播 Promise 回调的现有设置对象。

作业回调记录具有表 28中列出的字段。

表 28:作业回调记录字段
字段名称 含义
[[Callback]] 一个函数对象 作业被调用时要调用的函数。
[[HostDefined]] 任何(默认值为empty 保留供宿主使用的字段。

9.5.2 HostMakeJobCallback ( callback )

宿主定义的抽象操作 HostMakeJobCallback 接受参数callback(一个函数对象)并返回一个作业回调记录

HostMakeJobCallback 的实现必须符合以下要求:

  • 它必须返回一个作业回调记录,其[[Callback]]字段是callback

HostMakeJobCallback 的默认实现在调用时执行以下步骤:

  1. 返回作业回调记录 { [[Callback]]: callback[[HostDefined]]: empty }。

不是网络浏览器的 ECMAScript 宿主必须使用 HostMakeJobCallback 的默认实现。

注意

这在将回调传递给负责其最终调度和运行的函数时调用。例如,promise.then(thenAction)在调用Promise.prototype.then时调用 MakeJobCallback 在调用Promise.prototype.then时调用 MakeJobCallback,而不是在调度反应作业时。

9.5.3 HostCallJobCallback ( jobCallback, V, argumentsList )

宿主定义的抽象操作 HostCallJobCallback 接受参数jobCallback(一个作业回调记录),V(一个ECMAScript 语言值)和argumentsList(一个列表由 ECMAScript 语言值组成)并返回正常完成,其中包含一个ECMAScript 语言值或一个抛出完成

HostCallJobCallback 的实现必须符合以下要求:

  • 它必须执行并返回调用(jobCallback.[[Callback]]VargumentsList)的结果。
注意

此要求意味着宿主不能更改本规范中定义的函数对象的[[Call]]行为。

HostCallJobCallback 的默认实现在调用时执行以下步骤:

  1. 断言IsCallable(jobCallback.[[Callback]]) 为true
  2. 返回?调用(jobCallback.[[Callback]]VargumentsList)的结果。

不是网络浏览器的 ECMAScript 宿主必须使用 HostCallJobCallback 的默认实现。

9.5.4 HostEnqueueGenericJob ( job, realm )

宿主定义的抽象操作 HostEnqueueGenericJob 接受参数job(一个作业抽象闭包)和realm(一个范围记录)并返回unused。它将job调度到realm所指示的代理的realm中,以便在将来的某个时间执行。这些抽象闭包旨在不受附加约束(如优先级和顺序)调度。

HostEnqueueGenericJob 的实现必须符合9.5中的要求。

9.5.5 HostEnqueuePromiseJob ( job, realm )

宿主定义的抽象操作 HostEnqueuePromiseJob 接受参数job(一个作业抽象闭包)和realm(一个范围记录null)并返回unused。它将job调度到将来的某个时间执行。用于该算法的抽象闭包旨在与处理 Promise 相关,或者以与 Promise 处理操作同等的优先级进行调度。

HostEnqueuePromiseJob 的实现必须符合9.5中的要求以及以下内容:

注意

通过NewPromiseResolveThenableJob返回的作业的realm通常是通过调用GetFunctionRealmthen函数对象上的结果。通过NewPromiseReactionJob返回的作业的realm通常是通过调用GetFunctionRealm在处理程序不是undefined时的结果。如果处理程序是undefined,则realmnull。对于这两种类型的作业,当GetFunctionRealm异常完成时(即在撤销的代理上调用),realm是调用GetFunctionRealm时的当前范围记录。当realmnull时,不会评估用户 ECMAScript 代码,也不会创建新的 ECMAScript 对象(例如错误对象)。WHATWG HTML 规范(https://html.spec.whatwg.org/),例如,使用realm检查运行脚本的能力和条目概念。

9.5.6 HostEnqueueTimeoutJob ( timeoutJob, realm, milliseconds )

宿主定义的抽象操作 HostEnqueueTimeoutJob 接受参数timeoutJob(一个作业抽象闭包),realm(一个范围记录)和milliseconds(一个非负有限数字)并返回unused。它将timeoutJob调度到realm所指示的代理的realm中,以便在至少milliseconds毫秒后执行。

HostEnqueueTimeoutJob 的实现必须符合9.5中的要求。

9.6 InitializeHostDefinedRealm ( )

抽象操作 InitializeHostDefinedRealm 不接受任何参数,返回一个包含 正常完成unused 或者一个 抛出完成。调用时,它执行以下步骤:

  1. realmCreateRealm() 的结果。
  2. newContext 为一个新的 执行上下文
  3. newContext 的 Function 设置为 null
  4. newContextRealm 设置为 realm
  5. newContext 的 ScriptOrModule 设置为 null
  6. newContext 推入 执行上下文栈newContext 现在是 运行中的执行上下文
  7. 如果 宿主 需要使用一个 特殊对象 作为 realm全局对象,则让 global 为以 宿主定义 的方式创建的此类对象。否则,让 globalundefined,表示应创建一个 普通对象 作为 全局对象
  8. 如果 宿主 需要 this 绑定在 realm 的全局作用域中返回一个不同于 全局对象 的对象,则让 thisValue 为以 宿主定义 的方式创建的此类对象。否则,让 thisValueundefined,表示 realm 的全局 this 绑定应为 全局对象
  9. 执行 SetRealmGlobalObject(realm, global, thisValue)。
  10. globalObj 为 ? SetDefaultGlobalBindings(realm) 的结果。
  11. globalObj 上创建任何 宿主定义全局对象属性。
  12. 返回 unused

9.7 Agents

一个代理包括一组ECMAScript执行上下文、一个执行上下文栈、一个运行中的执行上下文、一个代理记录和一个执行线程。除了执行线程之外,代理的组成部分完全属于该代理

一个代理执行线程独立于其他代理在其执行上下文上执行算法步骤,除非一个执行线程可被多个代理共享,前提是共享该线程的代理没有代理记录[[CanBlock]]字段为true

注1

一些网络浏览器会在多个不相关的浏览器窗口标签页之间共享单个执行线程

当一个代理执行线程正在执行算法步骤时,该代理就是这些步骤的外围代理。这些步骤使用外围代理来访问在代理内保存的规范级执行对象:运行中的执行上下文执行上下文栈代理记录的字段。

一个代理标识符是一个全局唯一的、不透明的值,用于标识一个代理

表29: 代理记录字段
字段名 含义
[[LittleEndian]] 布尔值 在算法GetValueFromBufferSetValueInBuffer中需要时,计算isLittleEndian参数的默认值。该选择是实现定义的,应该是对实现最有效的替代方案。一旦该值被观察到,它就不能改变。
[[CanBlock]] 布尔值 确定代理是否可以阻塞。
[[Signifier]] 一个代理标识符 唯一标识其代理在其代理集群中的位置。
[[IsLockFree1]] 布尔值 如果对一个字节大小值的原子操作是无锁的,则为true,否则为false
[[IsLockFree2]] 布尔值 如果对两字节大小值的原子操作是无锁的,则为true,否则为false
[[IsLockFree8]] 布尔值 如果对八字节大小值的原子操作是无锁的,则为true,否则为false
[[CandidateExecution]] 一个候选执行记录 参见内存模型
[[KeptAlive]] 一个列表,包括对象或符号 最初是一个新的空列表,表示在当前任务结束前需要保持存活的对象和/或符号的列表。

一旦[[Signifier]][[IsLockFree1]][[IsLockFree2]]的值被任何代理在其代理集群中观察到,它们就不能改变。

注2

[[IsLockFree1]][[IsLockFree2]]的值不一定由硬件决定,还可能反映出可能随时间和不同ECMAScript实现而变化的实现选择。

没有[[IsLockFree4]]字段:四字节原子操作总是无锁的。

实际上,如果一个原子操作的实现使用了任何类型的锁,则该操作就不是无锁的。无锁不意味着无等待:没有关于完成无锁原子操作需要多少机器步骤的上限。

原子访问大小为n是无锁的,并不意味着对非原子访问大小为n的访问有任何暗示,特别是,非原子访问仍可能作为一系列单独的内存访问执行。详见ReadSharedMemoryWriteSharedMemory

注3

一个代理是一个规范机制,不必对应于ECMAScript实现的任何特定工件。

9.7.1 AgentSignifier ( )

抽象操作 AgentSignifier 不接受任何参数,并返回一个代理标识符。调用时,它执行以下步骤:

  1. AR代理记录,属于外围代理
  2. 返回 AR.[[Signifier]]

9.7.2 AgentCanSuspend ( )

抽象操作 AgentCanSuspend 不接受任何参数,并返回一个布尔值。调用时,它执行以下步骤:

  1. AR代理记录,属于外围代理
  2. 返回 AR.[[CanBlock]]

在某些环境中,允许给定代理挂起可能是不合理的。例如,在网络浏览器环境中,可能不允许挂起文档的主事件处理线程,同时仍然允许工作线程的事件处理线程挂起。

9.8 代理集群

一个代理集群是可以通过操作共享内存进行通信的代理的最大集合。

注1

不同代理中的程序可能通过未指定的方法共享内存。至少,SharedArrayBuffers的底层内存可以在集群中的代理之间共享。

可能有一些代理可以通过消息传递进行通信,但不能共享内存;它们永远不会在同一个代理集群中。

每个代理只属于一个代理集群。

注2

集群中的代理不需要在某个特定时间点都存活。如果代理A创建了另一个代理B,之后A终止,而B创建了代理C,如果A可以与B共享某些内存且B可以与C共享某些内存,那么这三个代理在同一个集群中。

集群中的所有代理在其各自的代理记录中的[[LittleEndian]]字段的值必须相同。

注3

如果一个代理集群中的不同代理[[LittleEndian]]值不同,则使用共享内存进行多字节数据操作会变得困难。

集群中的所有代理在其各自的代理记录中的[[IsLockFree1]]字段的值必须相同;同样适用于[[IsLockFree2]]字段。

集群中的所有代理在其各自的代理记录中的[[Signifier]]字段的值必须不同。

嵌入环境可以在不通知或合作代理的情况下停用(停止前进进程)或激活(恢复前进进程)一个代理。如果嵌入环境这样做,它必须确保集群中的一些代理在其他代理被无限期停用时不继续活动。

注4

上述限制的目的是避免出现某个代理由于另一个代理被停用而死锁或饿死的情况。例如,如果HTML共享工作者的生命周期独立于任何窗口中的文档,并允许其与这样的独立文档的专用工作者共享内存,而该文档及其专用工作者在持有锁时被停用(例如,文档被推入窗口的历史记录中),然后共享工作者尝试获取锁,则共享工作者将被阻塞直到专用工作者再次激活(如果有的话)。同时,尝试从其他窗口访问共享工作者的其他工作者将饿死。

这一限制的含义是,在嵌入环境中,不可能在不属于同一挂起/唤醒集体的代理之间共享内存。

嵌入环境可以在不通知或合作集群中其他代理的情况下终止一个代理。如果一个代理不是由其自身或集群中另一个代理通过编程方式终止,而是由集群外部的力量终止,那么嵌入环境必须选择以下两种策略之一:要么终止集群中的所有代理,要么提供可靠的API,使集群中的代理能够协调,以便集群中至少有一个剩余成员能够检测到终止,并且终止数据包含足够的信息来识别被终止的代理

注5

这种终止的例子包括:操作系统或用户终止在不同进程中运行的代理;当每个代理的资源核算表明代理是失控时,嵌入环境本身终止与其他代理在同一进程中运行的代理

每个以下的规范值及从它们递归可达的值,只属于一个代理集群。

在集群中任何代理评估任何ECMAScript代码之前,集群中所有代理代理记录中的[[CandidateExecution]]字段被设置为初始的候选执行。初始的候选执行是一个空的候选执行,其[[EventsRecords]]字段是一个列表,其中包含每个代理代理事件记录,其[[AgentSignifier]]字段是该代理代理标识符,其[[EventList]][[AgentSynchronizesWith]]字段是空的列表

注6

一个代理集群中的所有代理共享其代理记录[[CandidateExecution]]字段中的同一个候选执行候选执行内存模型使用的规范机制。

注7

代理集群是一个规范机制,不必对应于ECMAScript实现的任何特定工件。

9.9 前进进度

对于一个代理来说,前进进度是指其根据本规范执行评估步骤。

代理运行执行上下文同步且无限期地等待外部事件时,该代理会变得阻塞。只有其代理记录[[CanBlock]]字段为true代理才会以这种方式阻塞。一个非阻塞代理是指不阻塞的代理。

实现必须确保:

这与内存模型中的活性保证一起,确保所有seq-cst写操作最终会对所有代理可见。

9.10 WeakRef 和 FinalizationRegistry 目标的处理模型

9.10.1 目标

本规范不保证任何对象或符号将被垃圾回收。对于那些不是存活的对象或符号,可能在很长一段时间后或永远不会被释放。因此,本规范在描述垃圾回收触发的行为时使用了“可能”一词。

WeakRefsFinalizationRegistrys的语义基于两个在特定时间点发生的操作:

  • 当调用WeakRef.prototype.deref时,如果未返回undefined,则被引用对象保持存活,以便随后的同步访问也返回相同的值。当使用ClearKeptObjects抽象操作进行同步工作时,此列表会被重置。
  • 当与FinalizationRegistry注册的对象或符号变得不可达时,可能会在同步 ECMAScript 执行完成后调用FinalizationRegistry的清理回调。清理通过CleanupFinalizationRegistry抽象操作进行。

这些操作(ClearKeptObjectsCleanupFinalizationRegistry)不会中断同步的 ECMAScript 执行。由于宿主可能会组装更长的同步 ECMAScript 执行运行,本规范将ClearKeptObjectsCleanupFinalizationRegistry的调度延迟到宿主环境

一些 ECMAScript 实现包括在后台运行的垃圾回收器实现,包括 ECMAScript 空闲时。让宿主环境调度CleanupFinalizationRegistry允许它恢复 ECMAScript 执行以运行终结器工作,这可能释放被占用的值,从而减少整体内存使用。

9.10.2 存活性

对于某些对象和/或符号的集合S,相对于S假设的 WeakRef-oblivious执行是指抽象操作WeakRefDeref的执行,该操作始终返回undefined

注 1
WeakRef-obliviousness 与存活性共同捕捉了两个概念。其一,WeakRef本身不会使其引用保持存活。其二,存活性的循环不意味着一个值是存活的。具体来说,如果确定v的存活性取决于确定WeakRef引用r的存活性,r的存活性不能假定v的存活性,这将是循环推理。
注 2
WeakRef-obliviousness 是在对象或符号集合上定义的,以解释循环。如果它在单个值上定义,那么一个在循环中的WeakRef引用将被视为存活,即使它的身份只是通过循环中的其他WeakRef引用观察到的。
注 3
通俗地说,我们认为单个对象或符号是存活的,如果包含它的每个集合都是存活的。

在评估过程中,如果对象和/或符号的集合S满足以下任一条件,则被认为是存活的

  • S中的任何元素都包含在任何代理[[KeptAlive]]列表中。
  • 存在一个有效的未来假设的 WeakRef-oblivious 执行,该执行观察S中任何值的身份。
注 4
上述第二个条件旨在捕捉这样的直觉:如果通过非WeakRef方式观察到一个值的身份,那么该值是存活的。可以通过观察严格的相等比较或观察将值用作 Map 中的键来观察值的身份。
注 5

对象或符号在字段、内部槽或属性中的存在并不意味着该值是存活的。例如,如果问题中的值从未传递回程序,则无法观察到它。

这是 WeakMap 中的键、WeakSet 的成员以及[[WeakRefTarget]][[UnregisterToken]]字段在FinalizationRegistry单元记录中的情况。

上述定义意味着,如果 WeakMap 中的键不是存活的,则其对应的值也不一定是存活的。

注 6
存活性是保证引擎不清空哪些WeakRefs的下限。此处定义的存活性是不可判定的。在实践中,引擎使用保守的近似方法,例如可达性。预计会有显著的实现灵活性。

9.10.3 执行

在任何时候,如果对象和/或符号的集合S不是存活的,ECMAScript 实现可以原子地执行以下步骤:

  1. 对于S的每个元素value,执行以下操作
    1. 对于每个WeakRef,如果ref[[WeakRefTarget]]value,则执行以下操作
      1. ref[[WeakRefTarget]]设置为empty
    2. 对于每个FinalizationRegistry,如果fg[[Cells]]包含一个记录,其中cell[[WeakRefTarget]]value,则执行以下操作
      1. cell[[WeakRefTarget]]设置为empty
      2. 可选地,执行HostEnqueueFinalizationRegistryCleanupJob(fg)。
    3. 对于每个 WeakMapmap,如果map[[WeakMapData]]包含一个记录,其中r[[Key]]value,则执行以下操作
      1. r[[Key]]设置为empty
      2. r[[Value]]设置为empty
    4. 对于每个 WeakSetset,如果set[[WeakSetData]]包含value,则执行以下操作
      1. 用值为empty的元素替换set[[WeakSetData]]中值为value的元素。
注 1

结合存活性的定义,本条款规定了实现可以应用的关于WeakRefs的优化。

有可能在不观察对象身份的情况下访问对象。允许对非逃逸对象的属性进行死变量消除和标量替换等优化,因此这些优化可以可观察地清空指向这些对象的WeakRefs

另一方面,如果可以观察到对象的身份,并且该对象位于WeakRef[[WeakRefTarget]]内部槽中,则禁止进行可观察地清空WeakRef的优化。

由于调用HostEnqueueFinalizationRegistryCleanupJob是可选的,注册在FinalizationRegistry中的对象不一定是存活的。实现可以因任何原因省略FinalizationRegistry回调,例如,如果FinalizationRegistry本身变得死掉,或如果应用程序正在关闭。

注 2

实现没有义务为最大集合的非存活对象或符号清空WeakRefs

如果实现选择一个非存活集合S来清空WeakRefs,则此定义要求它同时清空S中所有值的WeakRefs。换句话说,实现不符合规范的行为是清空指向值vWeakRef,而不清空其他可能导致观察到v值的WeakRefs

9.10.4 宿主钩子

9.10.4.1 HostEnqueueFinalizationRegistryCleanupJob (finalizationRegistry)

宿主定义的抽象操作 HostEnqueueFinalizationRegistryCleanupJob 接受参数finalizationRegistry(一个FinalizationRegistry)并返回unused

cleanupJob成为一个新的作业抽象闭包,没有参数,捕获finalizationRegistry并在调用时执行以下步骤:

  1. cleanupResult完成(CleanupFinalizationRegistry(finalizationRegistry))。
  2. 如果cleanupResult是一个异常完成,执行任何宿主定义的步骤来报告错误。
  3. 返回unused

HostEnqueueFinalizationRegistryCleanupJob 的实现会安排在将来的某个时间执行cleanupJob,如果可能的话。它还必须符合9.5中的要求。

9.11 ClearKeptObjects ( )

抽象操作 ClearKeptObjects 不接受任何参数并返回 unused。期望 ECMAScript 实现会在一系列同步的 ECMAScript 执行完成时调用 ClearKeptObjects。调用该操作时执行以下步骤:

  1. agentRecord 成为 周围代理代理记录
  2. agentRecord.[[KeptAlive]] 设置为一个新的空的 列表
  3. 返回 unused

9.12 AddToKeptObjects ( value )

抽象操作 AddToKeptObjects 接受参数 value(一个对象或符号)并返回 unused。调用该操作时执行以下步骤:

  1. agentRecord 成为 周围代理代理记录
  2. value 添加到 agentRecord.[[KeptAlive]]
  3. 返回 unused
当抽象操作 AddToKeptObjects 被调用并传入目标对象或符号时,它会将目标添加到一个列表中,该列表会强引用该目标,直到调用 ClearKeptObjects

9.13 CleanupFinalizationRegistry ( finalizationRegistry )

抽象操作 CleanupFinalizationRegistry 接受参数 finalizationRegistry(一个 FinalizationRegistry),并返回 正常完成记录,包含 unused抛出完成记录。调用该操作时执行以下步骤:

  1. 断言finalizationRegistry 具有 [[Cells]][[CleanupCallback]] 内部槽。
  2. callbackfinalizationRegistry.[[CleanupCallback]]
  3. finalizationRegistry.[[Cells]] 包含一个 记录 cell,其 [[WeakRefTarget]]empty 时,实现可以执行以下步骤:
    1. 选择任意这样的 cell
    2. finalizationRegistry.[[Cells]] 中移除 cell
    3. 执行 ? HostCallJobCallback(callback, undefined, « cell.[[HeldValue]] »)。
  4. 返回 unused

9.14 CanBeHeldWeakly ( v )

抽象操作 CanBeHeldWeakly 接受参数 v(一个 ECMAScript 语言值),并返回一个布尔值。仅当 v 适合用作弱引用时,它才返回 true。只有适合用作弱引用的值才可以作为 WeakMap 的键、WeakSet 的元素、WeakRef 的目标,或 FinalizationRegistry 的目标之一。调用该操作时执行以下步骤:

  1. 如果 v 是一个对象,返回 true
  2. 如果 v 是一个符号,并且 KeyForSymbol(v) 是 undefined,返回 true
  3. 返回 false

没有 语言身份 的语言值可以在没有先前引用的情况下显现出来,不适合用作弱引用。通过 Symbol.for 产生的符号值与其他符号值不同,它没有语言身份,因此不适合用作弱引用。众所周知的符号 可能永远不会被收集,但仍被视为适合用作弱引用,因为它们数量有限,可以通过多种实现方法进行管理。然而,在 活动 WeakMap 中与众所周知符号关联的任何值都不太可能被收集,并且可能在实现中“泄漏”内存资源。

10 普通对象和奇异对象的行为

10.1 普通对象的内部方法和内部槽

所有的 普通对象 都有一个名为 [[Prototype]] 的内部槽。这个内部槽的值可以是 null 或一个对象,用于实现继承。假设某个名为 P 的属性在一个 普通对象 O 中缺失,但在其 [[Prototype]] 对象上存在。如果 P 指向 数据属性,则 O 会继承该属性以进行读取操作,使其行为如同 PO 的一个属性一样。如果 P 指向 [[Prototype]] 对象上的一个可写的 数据属性,则在 O 上设置 P 的访问将会创建一个新的名为 P数据属性。如果 P 指向 [[Prototype]] 对象上的一个不可写的 数据属性,则在 O 上设置 P 的访问将会失败。如果 P 指向 访问器属性,该访问器将被 O 继承,以进行读取和设置操作。

每个 普通对象 都有一个布尔值的 [[Extensible]] 内部槽,用于满足 6.1.7.3 中规定的与可扩展性相关的内部方法不变性。也就是说,一旦对象的 [[Extensible]] 内部槽的值被设置为 false,就不能再向对象添加属性,也不能修改对象的 [[Prototype]] 内部槽的值,或者随后将 [[Extensible]] 的值更改为 true

在以下算法描述中,假设 O 是一个 普通对象P 是一个 属性键 值,V 是任何 ECMAScript 语言值,而 Desc 是一个 属性描述符 记录。

每个 普通对象 的内部方法都委托给一个同名的抽象操作。如果这样的抽象操作依赖于另一个内部方法,那么内部方法将会在 O 上被调用,而不是直接调用同名的抽象操作。这些语义确保了 异国对象 在应用普通对象的内部方法时,其被重写的内部方法会被调用。

10.1.1 [[GetPrototypeOf]] ( )

[[GetPrototypeOf]] 内部方法用于一个 普通对象 O,不接受任何参数,返回一个 正常的完成记录,其值为一个对象或 null。调用时执行以下步骤:

  1. 返回 OrdinaryGetPrototypeOf(O)。

10.1.1.1 OrdinaryGetPrototypeOf ( O )

抽象操作 OrdinaryGetPrototypeOf 接受一个参数 O(一个对象),并返回一个对象或 null。调用时执行以下步骤:

  1. 返回 O.[[Prototype]]

10.1.2 [[SetPrototypeOf]] ( V )

[[SetPrototypeOf]] 内部方法用于一个 普通对象 O,接受一个参数 V(一个对象或 null),并返回一个 正常的完成记录,其值为布尔值。调用时执行以下步骤:

  1. 返回 OrdinarySetPrototypeOf(O, V)。

10.1.2.1 OrdinarySetPrototypeOf ( O, V )

抽象操作 OrdinarySetPrototypeOf 接受两个参数:O(一个对象)和 V(一个对象或 null),并返回一个布尔值。调用时执行以下步骤:

  1. current 设为 O.[[Prototype]]
  2. 如果 SameValue(V, current) 为 true,则返回 true
  3. extensible 设为 O.[[Extensible]]
  4. 如果 extensiblefalse,则返回 false
  5. p 设为 V
  6. done 设为 false
  7. 重复以下步骤,直到 donetrue
    1. 如果 pnull,则
      1. done 设为 true
    2. 否则,如果 SameValue(p, O) 为 true,则
      1. 返回 false
    3. 否则,
      1. 如果 p.[[GetPrototypeOf]] 不是在 普通对象 内部方法中定义的 10.1.1,则将 done 设为 true
      2. 否则,将 p 设为 p.[[Prototype]]
  8. O.[[Prototype]] 设为 V
  9. 返回 true
注意

步骤 7 中的循环保证了在原型链中只包含使用 普通对象 定义的 [[GetPrototypeOf]][[SetPrototypeOf]] 的对象时,不会出现循环。

10.1.3 [[IsExtensible]] ( )

[[IsExtensible]] 内部方法用于一个 普通对象 O,不接受参数,并返回一个 正常的完成记录,其值为布尔值。调用时执行以下步骤:

  1. 返回 OrdinaryIsExtensible(O)。

10.1.3.1 OrdinaryIsExtensible ( O )

抽象操作 OrdinaryIsExtensible 接受一个参数 O(一个对象),并返回一个布尔值。调用时执行以下步骤:

  1. 返回 O.[[Extensible]]

10.1.4 [[PreventExtensions]] ( )

[[PreventExtensions]] 内部方法用于一个 普通对象 O,不接受参数,并返回一个 正常的完成记录,其值为 true。调用时执行以下步骤:

  1. 返回 OrdinaryPreventExtensions(O)。

10.1.4.1 OrdinaryPreventExtensions ( O )

抽象操作 OrdinaryPreventExtensions 接受一个参数 O(一个对象),并返回 true。调用时执行以下步骤:

  1. O.[[Extensible]] 设置为 false
  2. 返回 true

10.1.5 [[GetOwnProperty]] ( P )

[[GetOwnProperty]] 内部方法用于一个 普通对象 O,接受一个参数 P(一个 属性键),并返回一个 正常的完成记录,其值可以是 属性描述符undefined。调用时执行以下步骤:

  1. 返回 OrdinaryGetOwnProperty(O, P)。

10.1.5.1 OrdinaryGetOwnProperty ( O, P )

抽象操作 OrdinaryGetOwnProperty 接受两个参数 O(一个对象)和 P(一个 属性键),并返回一个 属性描述符undefined。调用时执行以下步骤:

  1. 如果 O 没有键为 P 的自身属性,则返回 undefined
  2. 创建一个新的 属性描述符 D,其字段为空。
  3. 获取 O 自身属性中键为 P 的属性 X
  4. 如果 X 是一个 数据属性,则:
    1. D.[[Value]] 设置为 X[[Value]] 属性值。
    2. D.[[Writable]] 设置为 X[[Writable]] 属性值。
  5. 否则:
    1. 断言X 是一个 访问器属性
    2. D.[[Get]] 设置为 X[[Get]] 属性值。
    3. D.[[Set]] 设置为 X[[Set]] 属性值。
  6. D.[[Enumerable]] 设置为 X[[Enumerable]] 属性值。
  7. D.[[Configurable]] 设置为 X[[Configurable]] 属性值。
  8. 返回 D

10.1.6 [[DefineOwnProperty]] ( P, Desc )

普通对象的 [[DefineOwnProperty]] 内部方法接受两个参数:P(一个 属性 键)和 Desc(一个 属性描述符), 并返回一个 正常完成, 包含一个布尔值或一个 抛出完成。 调用时,它执行以下步骤:

  1. 返回 ? OrdinaryDefineOwnProperty(O, P, Desc).

10.1.6.1 OrdinaryDefineOwnProperty(O, P, Desc

抽象操作 OrdinaryDefineOwnProperty 接受参数 O(一个对象)、P(一个属性键),和 Desc(一个属性描述符),并返回一个包含布尔值的正常完成或一个抛出完成。当被调用时,它执行以下步骤:

  1. current 为 ? O.[[GetOwnProperty]](P)。
  2. extensible 为 ? IsExtensible(O)。
  3. 返回 ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current)。

10.1.6.2 IsCompatiblePropertyDescriptor(Extensible, Desc, Current

抽象操作 IsCompatiblePropertyDescriptor 接受参数 Extensible(一个布尔值)、Desc(一个属性描述符),和 Current(一个属性描述符undefined),并返回一个布尔值。当被调用时,它执行以下步骤:

  1. 返回 ValidateAndApplyPropertyDescriptor(undefined, "", Extensible, Desc, Current)。

10.1.6.3 ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current

抽象操作 ValidateAndApplyPropertyDescriptor 接受参数 O(一个对象或undefined)、P(一个属性键)、extensible(一个布尔值)、Desc(一个属性描述符),和 current(一个属性描述符undefined),并返回一个布尔值。只有当 Desc 可以作为具有指定扩展性和当前属性current的对象的属性应用时,同时保持不变量时,它才返回 true。当这种应用是可能的且O不是undefined时,它会为名为P的属性执行该应用(如有必要,创建该属性)。当被调用时,它执行以下步骤:

  1. 断言IsPropertyKey(P) 是 true
  2. 如果 currentundefined,则
    1. 如果 extensiblefalse,返回 false
    2. 如果 Oundefined,返回 true
    3. 如果 IsAccessorDescriptor(Desc) 是 true,则
      1. 为对象 O 创建一个名为 P存取器属性,其 [[Get]][[Set]][[Enumerable]][[Configurable]] 属性设置为 Desc 中相应字段的值,如果 Desc 有该字段,则设置为该字段的值,否则设置为属性的默认值
    4. 否则,
      1. 为对象 O 创建一个名为 P数据属性,其 [[Value]][[Writable]][[Enumerable]][[Configurable]] 属性设置为 Desc 中相应字段的值,如果 Desc 有该字段,则设置为该字段的值,否则设置为属性的默认值
    5. 返回 true
  3. 断言current 是一个完全填充的属性描述符
  4. 如果 Desc 没有任何字段,返回 true
  5. 如果 current.[[Configurable]]false,则
    1. 如果 Desc 有一个 [[Configurable]] 字段且 Desc.[[Configurable]]true,返回 false
    2. 如果 Desc 有一个 [[Enumerable]] 字段且 Desc.[[Enumerable]] 不等于 current.[[Enumerable]],返回 false
    3. 如果 IsGenericDescriptor(Desc) 是 false 并且 IsAccessorDescriptor(Desc) 不等于 IsAccessorDescriptor(current),返回 false
    4. 如果 IsAccessorDescriptor(current) 是 true,则
      1. 如果 Desc 有一个 [[Get]] 字段且 SameValue(Desc.[[Get]], current.[[Get]]) 是 false,返回 false
      2. 如果 Desc 有一个 [[Set]] 字段且 SameValue(Desc.[[Set]], current.[[Set]]) 是 false,返回 false
    5. 否则,如果 current.[[Writable]]false,则
      1. 如果 Desc 有一个 [[Writable]] 字段且 Desc.[[Writable]]true,返回 false
      2. 如果 Desc 有一个 [[Value]] 字段且 SameValue(Desc.[[Value]], current.[[Value]]) 是 false,返回 false
  6. 如果 O 不是 undefined,则
    1. 如果 IsDataDescriptor(current) 是 trueIsAccessorDescriptor(Desc) 是 true,则
      1. 如果 Desc 有一个 [[Configurable]] 字段,令 configurableDesc.[[Configurable]];否则令 configurablecurrent.[[Configurable]]
      2. 如果 Desc 有一个 [[Enumerable]] 字段,令 enumerableDesc.[[Enumerable]];否则令 enumerablecurrent.[[Enumerable]]
      3. 替换对象 O 中名为 P 的属性为一个存取器属性,其 [[Configurable]][[Enumerable]] 属性分别设置为 configurableenumerable,其 [[Get]][[Set]] 属性设置为 Desc 中相应字段的值,如果 Desc 有该字段,则设置为该字段的值,否则设置为属性的默认值
    2. 否则,如果 IsAccessorDescriptor(current) 是 trueIsDataDescriptor(Desc) 是 true,则
      1. 如果 Desc 有一个 [[Configurable]] 字段,令 configurableDesc.[[Configurable]];否则令 configurablecurrent.[[Configurable]]
      2. 如果 Desc 有一个 [[Enumerable]] 字段,令 enumerableDesc.[[Enumerable]];否则令 enumerablecurrent.[[Enumerable]]
      3. 替换对象 O 中名为 P 的属性为一个数据属性,其 [[Configurable]][[Enumerable]] 属性分别设置为 configurableenumerable,其 [[Value]][[Writable]] 属性设置为 Desc 中相应字段的值,如果 Desc 有该字段,则设置为该字段的值,否则设置为属性的默认值
    3. 否则,
      1. 对于 Desc 的每个字段,将对象 O 中名为 P 的属性的相应属性设置为该字段的值。
  7. 返回 true

10.1.7 [[HasProperty]]P

一个普通对象[[HasProperty]]内部方法接受参数P(一个属性键),并返回一个包含布尔值的正常完成或一个抛出完成。当被调用时,它执行以下步骤:

  1. 返回 ? OrdinaryHasPropertyO, P)。

10.1.7.1 OrdinaryHasProperty(O, P

抽象操作 OrdinaryHasProperty 接受参数 O(一个对象)和 P(一个属性键),并返回一个包含布尔值的正常完成或一个抛出完成。当被调用时,它执行以下步骤:

  1. hasOwn 为 ? O.[[GetOwnProperty]](P)。
  2. 如果 hasOwn 不是 undefined,返回 true
  3. parent 为 ? O.[[GetPrototypeOf]]()。
  4. 如果 parent 不是 null,则
    1. 返回 ? parent.[[HasProperty]](P)。
  5. 返回 false

10.1.8 [[Get]] ( P, Receiver )

[[Get]] 内部方法用于一个 普通对象 O,接受参数 P(一个 属性键)和 Receiver(一个 ECMAScript 语言值),并返回一个 正常完成记录,其中包含一个 ECMAScript 语言值,或者一个 抛出完成记录。调用时执行以下步骤:

  1. 返回 ? OrdinaryGet(O, P, Receiver).

10.1.8.1 OrdinaryGet ( O, P, Receiver )

抽象操作 OrdinaryGet 接受参数 O(一个对象)、P(一个 属性键)和 Receiver(一个 ECMAScript 语言值),并返回一个 正常完成记录,其中包含一个 ECMAScript 语言值,或者一个 抛出完成记录。调用时执行以下步骤:

  1. desc 等于 ? O.[[GetOwnProperty]](P)。
  2. 如果 descundefined,则
    1. parent 等于 ? O.[[GetPrototypeOf]]()。
    2. 如果 parentnull,返回 undefined
    3. 返回 ? parent.[[Get]](P, Receiver)。
  3. 如果 IsDataDescriptor(desc) 是 true,返回 desc.[[Value]]
  4. 断言: IsAccessorDescriptor(desc) 是 true
  5. getter 等于 desc.[[Get]]
  6. 如果 getterundefined,返回 undefined
  7. 返回 ? Call(getter, Receiver)。

10.1.9 [[Set]] ( P, V, Receiver )

普通对象(ordinary objectO[[Set]] 内部方法接受三个参数:P(属性键),V(ECMAScript 语言值),和 Receiver(ECMAScript 语言值),并返回一个完成记录,可能是包含布尔值的正常完成记录,也可能是抛出异常的完成记录。调用时执行以下步骤:

  1. 返回 ? OrdinarySet(O, P, V, Receiver)。

10.1.9.1 OrdinarySet ( O, P, V, Receiver )

抽象操作 OrdinarySet 接受四个参数:O(对象),P(属性键),V(ECMAScript 语言值),和 Receiver(ECMAScript 语言值),并返回一个完成记录,可能是包含布尔值的正常完成记录,也可能是抛出异常的完成记录。调用时执行以下步骤:

  1. ownDesc 为 ? O.[[GetOwnProperty]](P)。
  2. 返回 ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc)。

10.1.9.2 OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc )

抽象操作 OrdinarySetWithOwnDescriptor 接受五个参数:O(对象),P(属性键),V(ECMAScript 语言值),Receiver(ECMAScript 语言值),和 ownDesc(属性描述符或 undefined),并返回一个完成记录,可能是包含布尔值的正常完成记录,也可能是抛出异常的完成记录。调用时执行以下步骤:

  1. 如果 ownDescundefined,则:
    1. parent 为 ? O.[[GetPrototypeOf]]()。
    2. 如果 parent 不为 null,则:
      1. 返回 ? parent.[[Set]](P, V, Receiver)。
    3. 否则:
      1. ownDesc 设置为属性描述符 {[[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}。
  2. 如果 IsDataDescriptor(ownDesc) 为 true,则:
    1. 如果 ownDesc.[[Writable]]false,返回 false
    2. 如果 Receiver 不是一个对象,返回 false
    3. existingDescriptor 为 ? Receiver.[[GetOwnProperty]](P)。
    4. 如果 existingDescriptor 不为 undefined,则:
      1. 如果 IsAccessorDescriptor(existingDescriptor) 为 true,返回 false
      2. 如果 existingDescriptor.[[Writable]]false,返回 false
      3. valueDesc 为属性描述符 {[[Value]]: V}。
      4. 返回 ? Receiver.[[DefineOwnProperty]](P, valueDesc)。
    5. 否则:
      1. Assert: Receiver 当前没有属性 P
      2. 返回 ? CreateDataProperty(Receiver, P, V)。
  3. Assert: IsAccessorDescriptor(ownDesc) 为 true
  4. setterownDesc.[[Set]]
  5. 如果 setterundefined,返回 false
  6. 执行 ? Call(setter, Receiver, «V»)。
  7. 返回 true

10.1.10 [[Delete]] ( P )

普通对象(ordinary objectO[[Delete]] 内部方法接受参数 P属性键),并返回一个包含布尔值的正常完成记录或一个抛出异常的完成记录。调用时执行以下步骤:

  1. 返回 ? OrdinaryDelete(O, P)。

10.1.10.1 OrdinaryDelete ( O, P )

抽象操作 OrdinaryDelete 接受两个参数:O(对象)和 P属性键),并返回一个包含布尔值的正常完成记录或一个抛出异常的完成记录。调用时执行以下步骤:

  1. desc 为 ? O.[[GetOwnProperty]](P)。
  2. 如果 descundefined,返回 true
  3. 如果 desc.[[Configurable]]true,则:
    1. O 中删除名称为 P 的自身属性。
    2. 返回 true
  4. 返回 false

10.1.11 [[OwnPropertyKeys]] ( )

普通对象(ordinary objectO[[OwnPropertyKeys]] 内部方法不接受任何参数,并返回一个包含 列表 的正常完成记录,该列表包含 属性键。调用时执行以下步骤:

  1. 返回 OrdinaryOwnPropertyKeys(O)。

10.1.11.1 OrdinaryOwnPropertyKeys ( O )

抽象操作 OrdinaryOwnPropertyKeys 接受一个参数 O(对象),并返回一个包含 列表属性键。调用时执行以下步骤:

  1. keys 为一个新的空 列表
  2. 对于 O 的每个自身 属性键 P,如果 P数组索引,按升序的数字索引顺序:
    1. P 添加到 keys 中。
  3. 对于 O 的每个自身 属性键 P,如果 P 是一个字符串P 不是 数组索引,按属性创建的升序时间顺序:
    1. P 添加到 keys 中。
  4. 对于 O 的每个自身 属性键 P,如果 P 是一个符号,按属性创建的升序时间顺序:
    1. P 添加到 keys 中。
  5. 返回 keys

10.1.12 OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] )

抽象操作 OrdinaryObjectCreate 接受参数 proto(一个对象或 null)以及可选参数 additionalInternalSlotsList(一个 列表,包含内部槽的名称),并返回一个对象。它用于指定新的 普通对象 的运行时创建。additionalInternalSlotsList 包含必须作为对象一部分定义的附加内部槽的名称,除了 [[Prototype]][[Extensible]]。如果未提供 additionalInternalSlotsList,则使用一个新的空 列表。调用时执行以下步骤:

  1. internalSlotsList 为 « [[Prototype]], [[Extensible]] »。
  2. 如果 additionalInternalSlotsList 存在,则将 internalSlotsList 设置为 列表连接 internalSlotsListadditionalInternalSlotsList 的结果。
  3. OMakeBasicObject(internalSlotsList)。
  4. O.[[Prototype]] 设置为 proto
  5. 返回 O

尽管 OrdinaryObjectCreate 仅调用 MakeBasicObject,但它的使用传达了创建 普通对象 的意图,而不是一种特殊的对象。因此,在该规范中,它不会被任何算法调用,这些算法随后会以使结果变为非普通的方式修改对象的内部方法。创建 特殊对象 的操作直接调用 MakeBasicObject

10.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )

抽象操作 OrdinaryCreateFromConstructor 接受参数 constructor(一个 构造函数)和 intrinsicDefaultProto(一个字符串),以及可选参数 internalSlotsList(一个 列表,包含内部槽的名称),并返回一个对象或抛出异常。它创建一个 普通对象,其 [[Prototype]] 值从 构造函数"prototype" 属性中获取(如果存在)。否则,使用由 intrinsicDefaultProto 指定的内建对象作为 [[Prototype]]internalSlotsList 包含必须作为对象一部分定义的附加内部槽的名称。如果未提供 internalSlotsList,则使用一个新的空 列表。调用时执行以下步骤:

  1. 断言: intrinsicDefaultProto 是本规范定义的内建对象的名称。对应的对象必须是一个内建对象,旨在作为对象的 [[Prototype]] 值。
  2. proto 为 ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto)。
  3. 如果 internalSlotsList 存在,令 slotsListinternalSlotsList
  4. 否则,令 slotsList 为一个新的空 列表
  5. 返回 OrdinaryObjectCreate(proto, slotsList)。

10.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )

抽象操作 GetPrototypeFromConstructor 接受参数 constructor(一个 函数对象)和 intrinsicDefaultProto(一个字符串),并返回一个对象或抛出异常。它确定在创建与特定 构造函数 对应的对象时应使用的 [[Prototype]] 值。该值从 构造函数"prototype" 属性中获取(如果存在)。否则,使用由 intrinsicDefaultProto 指定的内建对象作为 [[Prototype]]。调用时执行以下步骤:

  1. 断言: intrinsicDefaultProto 是本规范定义的内建对象的名称。对应的对象必须是一个内建对象,旨在作为对象的 [[Prototype]] 值。
  2. proto 为 ? Get(constructor, "prototype")。
  3. 如果 proto 不是一个对象,则
    1. realm 为 ? GetFunctionRealm(constructor)。
    2. proto 设置为 realm 的名为 intrinsicDefaultProto 的内建对象。
  4. 返回 proto
注意

如果 constructor 没有提供 [[Prototype]] 值,则使用的默认值是从 领域constructor 函数获取的,而不是从 正在执行的上下文 中获取。

10.1.15 RequireInternalSlot ( O, internalSlot )

抽象操作 RequireInternalSlot 接受参数 O(一个 ECMAScript 语言值)和 internalSlot(一个内部槽名称),并返回一个正常的完成包含 unused 或一个抛出完成。除非 O 是一个对象 并且具有给定的内部槽,否则会抛出异常。调用时执行以下步骤:

  1. 如果 O 不是一个对象,则抛出一个 TypeError 异常。
  2. 如果 O 不具有一个 internalSlot 内部槽,则抛出一个 TypeError 异常。
  3. 返回 unused

10.2 ECMAScript 函数对象

ECMAScript 函数对象 封装了参数化的 ECMAScript 代码,并将其封闭在词法环境中,支持对该代码的动态求值。一个 ECMAScript 函数对象 是一个 普通对象,并且具有与其他 普通对象 相同的内部槽和内部方法。一个 ECMAScript 函数对象 的代码可以是 严格模式代码(见 11.2.2)或 非严格模式代码。一个 ECMAScript 函数对象 的代码是 严格模式代码 的,被称为 严格函数。如果代码不是 严格模式代码,则称为 非严格函数

除了 [[Extensible]][[Prototype]] 外,ECMAScript 函数对象 还有在 表 30 中列出的内部槽。

表 30: ECMAScript 函数对象的内部槽
内部槽 类型 描述
[[Environment]] 一个 环境记录 函数封闭的 环境记录。在评估函数代码时用作外部环境。
[[PrivateEnvironment]] 一个 PrivateEnvironment 记录null 函数封闭的 PrivateEnvironment 记录。如果该函数没有语法上包含在类中,则为 null。在评估函数代码时,作为内部类的外部 PrivateEnvironment 使用。
[[FormalParameters]] 一个 解析节点 定义函数正式参数列表的源文本的根解析节点。
[[ECMAScriptCode]] 一个 解析节点 定义函数主体的源文本的根解析节点。
[[ConstructorKind]] basederived 函数是否是派生类 构造函数
[[Realm]] 一个 Realm 记录 函数创建的 realm,提供在评估函数时访问的任何内建对象。
[[ScriptOrModule]] 一个 脚本记录模块记录 函数创建的脚本或模块。
[[ThisMode]] lexicalstrictglobal 定义 this 引用在函数的正式参数和代码体内如何被解释。lexical 表示 this 指向词法上封闭函数的 this 值。strict 表示 this 值正好按照函数调用时提供的值使用。global 表示 this 值为 undefinednull 时解释为对 全局对象 的引用,其他的 this 值则首先传递给 ToObject
[[Strict]] 一个布尔值 如果这是一个 严格函数,则为 true;如果这是一个 非严格函数,则为 false
[[HomeObject]] 一个对象 如果函数使用了 super,这是提供 [[GetPrototypeOf]] 的对象,从而开始 super 属性的查找。
[[SourceText]] 一系列 Unicode 码点 定义函数的 源文本
[[Fields]] 一个 列表ClassFieldDefinition 记录 如果函数是一个类,则这是一个列表,表示类的非静态字段及其对应的初始化器。
[[PrivateMethods]] 一个 列表PrivateElements 如果函数是一个类,则这是一个列表,表示类的非静态私有方法和访问器。
[[ClassFieldInitializerName]] 一个字符串、一个符号、一个 私有名称empty 如果函数作为类字段的初始化器创建,则用于 NamedEvaluation 的名称;否则为 empty
[[IsClassConstructor]] 一个布尔值 指示函数是否是一个类 构造函数。如果为 true,调用该函数的 [[Call]] 将立即抛出 TypeError 异常。

所有 ECMAScript 函数对象 都有这里定义的 [[Call]] 内部方法。此外,ECMAScript 函数如果也是 构造函数,则还有 [[Construct]] 内部方法。

10.2.1 [[Call]] ( thisArgument, argumentsList )

ECMAScript 函数对象 F[[Call]] 内部方法接受参数 thisArgument(一个 ECMAScript 语言值)和 argumentsList(一个 列表,包含 ECMAScript 语言值),并返回一个 正常完成(包含一个 ECMAScript 语言值)或者一个 抛出完成。调用时执行以下步骤:

  1. callerContext当前执行上下文
  2. calleeContextPrepareForOrdinaryCall(F, undefined)。
  3. 断言: calleeContext 现在是 当前执行上下文
  4. 如果 F.[[IsClassConstructor]]true,则
    1. error 为一个新创建的 TypeError 对象。
    2. 注意:error 是在 calleeContext 中创建的,使用 F 关联的 领域记录
    3. 执行上下文栈 中移除 calleeContext,并将 callerContext 恢复为 当前执行上下文
    4. 返回 ThrowCompletion(error)。
  5. 执行 OrdinaryCallBindThis(F, calleeContext, thisArgument)。
  6. resultCompletion(OrdinaryCallEvaluateBody(F, argumentsList))。
  7. 执行上下文栈 中移除 calleeContext,并将 callerContext 恢复为 当前执行上下文
  8. 如果 result 是一个 返回完成,返回 result.[[Value]]
  9. ReturnIfAbrupt(result)。
  10. 返回 undefined
注意

当在步骤 7 中从 执行上下文栈 中移除 calleeContext 时,如果它是挂起的并被生成器保留以便以后恢复,则不得销毁它。

10.2.1.1 PrepareForOrdinaryCall ( F, newTarget )

抽象操作 PrepareForOrdinaryCall 接受参数 F(一个 ECMAScript 函数对象)和 newTarget(一个对象或 undefined),并返回一个 执行上下文。它在调用时执行以下步骤:

  1. callerContext当前执行上下文
  2. calleeContext 为一个新的 ECMAScript 代码执行上下文
  3. calleeContext 的函数设置为 F
  4. calleeRealmF.[[Realm]]
  5. calleeContext领域 设置为 calleeRealm
  6. calleeContext 的 ScriptOrModule 设置为 F.[[ScriptOrModule]]
  7. localEnvNewFunctionEnvironment(F, newTarget)。
  8. calleeContext 的词法环境设置为 localEnv
  9. calleeContext 的变量环境设置为 localEnv
  10. calleeContext 的私有环境设置为 F.[[PrivateEnvironment]]
  11. 如果 callerContext 尚未被挂起,则挂起 callerContext
  12. calleeContext 推入 执行上下文栈calleeContext 现在是 当前执行上下文
  13. 注意:此后产生的任何异常对象都与 calleeRealm 关联。
  14. 返回 calleeContext

10.2.1.2 OrdinaryCallBindThis ( F, calleeContext, thisArgument )

抽象操作 OrdinaryCallBindThis 接受参数 F(一个 ECMAScript 函数对象)、calleeContext(一个 执行上下文)以及 thisArgument(一个 ECMAScript 语言值),并返回 unused。它在调用时执行以下步骤:

  1. thisModeF.[[ThisMode]]
  2. 如果 thisModelexical,则返回 unused
  3. calleeRealmF.[[Realm]]
  4. localEnvcalleeContext 的词法环境。
  5. 如果 thisModestrict,则:
    1. thisValuethisArgument
  6. 否则:
    1. 如果 thisArgumentundefinednull,则:
      1. globalEnvcalleeRealm.[[GlobalEnv]]
      2. Assert: globalEnv 是一个 全局环境记录
      3. thisValueglobalEnv.[[GlobalThisValue]]
    2. 否则:
      1. thisValue 为 ! ToObject(thisArgument)。
      2. 注意:ToObject 使用 calleeRealm 生成包装对象。
  7. Assert: localEnv 是一个 函数环境记录
  8. Assert: 下一步不会返回 突发完成,因为 localEnv.[[ThisBindingStatus]] 不是 initialized
  9. 执行 ! localEnv.BindThisValue(thisValue)。
  10. 返回 unused

10.2.1.3 运行时语义:EvaluateBody

语法驱动操作 语法驱动操作 EvaluateBody 接受两个参数:functionObject(一个 ECMAScript 函数对象)和 argumentsList(一个 列表,包含 ECMAScript 语言值),并返回一个 正常完成记录, 包含一个 ECMAScript 语言值 或者一个 突发完成记录。它在以下产生式中被分段定义:

FunctionBody : FunctionStatementList
  1. 返回 ? EvaluateFunctionBodyFunctionBody,参数为 functionObjectargumentsList
ConciseBody : ExpressionBody
  1. 返回 ? EvaluateConciseBodyConciseBody,参数为 functionObjectargumentsList
GeneratorBody : FunctionBody
  1. 返回 ? EvaluateGeneratorBodyGeneratorBody,参数为 functionObjectargumentsList
AsyncGeneratorBody : FunctionBody
  1. 返回 ? EvaluateAsyncGeneratorBodyAsyncGeneratorBody,参数为 functionObjectargumentsList
AsyncFunctionBody : FunctionBody
  1. 返回 ? EvaluateAsyncFunctionBodyAsyncFunctionBody,参数为 functionObjectargumentsList
AsyncConciseBody : ExpressionBody
  1. 返回 ? EvaluateAsyncConciseBodyAsyncConciseBody,参数为 functionObjectargumentsList
Initializer : = AssignmentExpression
  1. 断言argumentsList 为空。
  2. 断言functionObject.[[ClassFieldInitializerName]] 不为空。
  3. 如果 IsAnonymousFunctionDefinition(AssignmentExpression) 为 true,则
    1. value 为 ? NamedEvaluationInitializer,参数为 functionObject.[[ClassFieldInitializerName]]
  4. 否则,
    1. rhs 为 ? EvaluationAssignmentExpression
    2. value 为 ? GetValue(rhs)。
  5. 返回 完成记录 { [[Type]]: return, [[Value]]: value, [[Target]]: empty }。
注释

尽管字段初始化器构成函数边界,调用 FunctionDeclarationInstantiation 没有任何可观察的效果,因此被省略。

ClassStaticBlockBody : ClassStaticBlockStatementList
  1. 断言argumentsList 为空。
  2. 返回 ? EvaluateClassStaticBlockBodyClassStaticBlockBody ,参数为 functionObject

10.2.1.4 OrdinaryCallEvaluateBody ( F, argumentsList )

抽象操作 OrdinaryCallEvaluateBody 接受两个参数:F(一个 ECMAScript 函数对象)和 argumentsList(一个 列表,包含 ECMAScript 语言值),并返回一个 正常完成记录, 包含一个 ECMAScript 语言值, 或者一个 突发完成记录。它在调用时执行以下步骤:

  1. 返回 ? EvaluateBodyF.[[ECMAScriptCode]],参数为 FargumentsList

10.2.2 [[Construct]] ( argumentsList, newTarget )

ECMAScript 函数对象 F[[Construct]] 内部方法接受两个参数:argumentsList(一个 列表,包含 ECMAScript 语言值)和 newTarget(一个 构造函数),并返回一个 正常完成记录,包含一个对象,或一个 抛出完成记录。它在调用时执行以下步骤:

  1. callerContext 为当前 运行执行上下文
  2. kindF.[[ConstructorKind]]
  3. 如果 kindbase,则
    1. thisArgument 为 ? OrdinaryCreateFromConstructor(newTarget, "%Object.prototype%")。
  4. calleeContextPrepareForOrdinaryCall(F, newTarget)。
  5. Assert: calleeContext 现在是 运行执行上下文
  6. 如果 kindbase,则
    1. 执行 OrdinaryCallBindThis(F, calleeContext, thisArgument)。
    2. initializeResultCompletion(InitializeInstanceElements(thisArgument, F))。
    3. 如果 initializeResult突发完成记录,则
      1. 执行上下文栈 中移除 calleeContext,并将 callerContext 恢复为 运行执行上下文
      2. 返回 ? initializeResult
  7. constructorEnvcalleeContext 的 LexicalEnvironment。
  8. resultCompletion(OrdinaryCallEvaluateBody(F, argumentsList))。
  9. 执行上下文栈 中移除 calleeContext,并将 callerContext 恢复为 运行执行上下文
  10. 如果 result返回完成记录,则
    1. 如果 result.[[Value]] 是一个对象,返回 result.[[Value]]
    2. 如果 kindbase,返回 thisArgument
    3. 如果 result.[[Value]] 不是 undefined,则抛出一个 TypeError 异常。
  11. 否则,
    1. ReturnIfAbrupt(result)。
  12. thisBinding 为 ? constructorEnv.GetThisBinding()。
  13. Assert: thisBinding 是一个对象
  14. 返回 thisBinding

10.2.3 OrdinaryFunctionCreate ( functionPrototype, sourceText, ParameterList, Body, thisMode, env, privateEnv )

抽象操作 OrdinaryFunctionCreate 接受以下参数:functionPrototype(一个对象), sourceText(一系列 Unicode 代码点),ParameterList(一个 解析节点), Body(一个 解析节点), thisModelexical-thisnon-lexical-this), env(一个 环境记录), 和 privateEnv(一个 私有环境记录null), 并返回一个 ECMAScript 函数对象。 它用于指定以默认的 [[Call]] 内部方法和无 [[Construct]] 内部方法(尽管可以通过像 MakeConstructor 这样的操作后续添加)的方式创建一个新函数。 sourceText 是要创建的函数的语法定义的源文本。调用时执行以下步骤:

  1. internalSlotsList表 30 中列出的内部槽。
  2. FOrdinaryObjectCreate(functionPrototype, internalSlotsList)。
  3. F.[[Call]] 设置为 10.2.1 中指定的定义。
  4. F.[[SourceText]] 设置为 sourceText
  5. F.[[FormalParameters]] 设置为 ParameterList
  6. F.[[ECMAScriptCode]] 设置为 Body
  7. 如果 source text matched by Body严格模式代码,则令 Stricttrue;否则令 Strictfalse
  8. F.[[Strict]] 设置为 Strict
  9. 如果 thisModelexical-this,则将 F.[[ThisMode]] 设置为 lexical
  10. 否则如果 Stricttrue,则将 F.[[ThisMode]] 设置为 strict
  11. 否则,将 F.[[ThisMode]] 设置为 global
  12. F.[[IsClassConstructor]] 设置为 false
  13. F.[[Environment]] 设置为 env
  14. F.[[PrivateEnvironment]] 设置为 privateEnv
  15. F.[[ScriptOrModule]] 设置为 GetActiveScriptOrModule()。
  16. F.[[Realm]] 设置为 当前 Realm 记录
  17. F.[[HomeObject]] 设置为 undefined
  18. F.[[Fields]] 设置为一个新的空的 列表
  19. F.[[PrivateMethods]] 设置为一个新的空的 列表
  20. F.[[ClassFieldInitializerName]] 设置为 empty
  21. lenParameterList 的期望参数数量。
  22. 执行 SetFunctionLength(F, len)。
  23. 返回 F

10.2.4 AddRestrictedFunctionProperties ( F, realm )

抽象操作 AddRestrictedFunctionProperties 接受两个参数:F(一个 函数对象) 和 realm(一个 Realm 记录),并返回 unused。 当调用时,它执行以下步骤:

  1. 断言: realm.[[Intrinsics]].[[%ThrowTypeError%]] 存在 并已初始化。
  2. throwerrealm.[[Intrinsics]].[[%ThrowTypeError%]]。
  3. 执行 ! DefinePropertyOrThrow(F, "caller", 属性描述符 { [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true }).
  4. 执行 ! DefinePropertyOrThrow(F, "arguments", 属性描述符 { [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true }).
  5. 返回 unused

10.2.4.1 %ThrowTypeError% ( )

这个函数是 %ThrowTypeError% 内在对象。

它是一个匿名的内置 函数对象,在每个 Realm 中定义一次。

当调用时,它执行以下步骤:

  1. 抛出一个 TypeError 异常。

这个函数的 [[Extensible]] 内部槽的值为 false

这个函数的 "length" 属性具有属性描述符 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

这个函数的 "name" 属性具有属性描述符 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

10.2.5 MakeConstructor ( F [ , writablePrototype [ , prototype ] ] )

抽象操作 MakeConstructor 接受一个参数 F(一个 ECMAScript 函数对象 或内置的 函数对象),以及可选参数 writablePrototype(一个布尔值)和 prototype(一个对象),并返回 unused。 它将 F 转换为一个 构造函数。当调用时,它执行以下步骤:

  1. 如果 F 是一个 ECMAScript 函数对象, 则
    1. 断言: IsConstructor(F) 为 false
    2. 断言: F 是一个可扩展的对象,且没有一个名为 "prototype" 的自身属性。
    3. F.[[Construct]] 设置为 在 10.2.2 中指定的定义。
  2. 否则,
    1. F.[[Construct]] 设置为 在 10.3.2 中指定的定义。
  3. F.[[ConstructorKind]] 设置为 base
  4. 如果 writablePrototype 不存在,将 writablePrototype 设置为 true
  5. 如果 prototype 不存在,则
    1. prototype 设置为 OrdinaryObjectCreate(%Object.prototype%)。
    2. 执行 ! DefinePropertyOrThrow(prototype, "constructor", 属性描述符 { [[Value]]: F, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: true }).
  6. 执行 ! DefinePropertyOrThrow(F, "prototype", 属性描述符 { [[Value]]: prototype, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: false }).
  7. 返回 unused

10.2.6 MakeClassConstructor ( F )

抽象操作 MakeClassConstructor 接受一个参数 F(一个 ECMAScript 函数对象),并返回 unused。当调用时,它执行以下步骤:

  1. 断言: F.[[IsClassConstructor]]false
  2. F.[[IsClassConstructor]] 设置为 true
  3. 返回 unused

10.2.7 MakeMethod ( F, homeObject )

抽象操作 MakeMethod 接受参数 F(一个 ECMAScript 函数对象)和 homeObject(一个对象),并返回 unused。 它将 F 配置为一个方法。当调用时,它执行以下步骤:

  1. F.[[HomeObject]] 设置为 homeObject
  2. 返回 unused

10.2.8 DefineMethodProperty ( homeObject, key, closure, enumerable )

抽象操作 DefineMethodProperty 接受四个参数:homeObject(一个对象),key(一个 属性键私有名称),closure(一个 函数对象),以及 enumerable(一个布尔值),并返回一个 正常完成记录, 其中包含一个 PrivateElementunused,或者是一个 突然完成。 当调用时,它执行以下步骤:

  1. 断言: homeObject 是一个普通的、可扩展的对象。
  2. 如果 key 是一个 私有名称,则
    1. 返回 PrivateElement { [[Key]]: key, [[Kind]]: method, [[Value]]: closure }。
  3. 否则,
    1. desc 为 PropertyDescriptor { [[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true }。
    2. 执行 ? DefinePropertyOrThrow(homeObject, key, desc)。
    3. 注:DefinePropertyOrThrow 仅在尝试定义一个类静态方法时,如果 key"prototype",才会返回 突然完成
    4. 返回 unused

10.2.9 SetFunctionName ( F, name [ , prefix ] )

抽象操作 SetFunctionName 接受两个必需参数和一个可选参数:F(一个 函数对象)和 name(一个 属性键私有名称),以及一个可选的 prefix(一个字符串),并返回 unused。它将一个 "name" 属性添加到 F 上。它在调用时执行以下步骤:

  1. 断言: F 是一个可扩展的对象,并且没有 "name" 自有属性。
  2. 如果 name 是一个符号,则
    1. descriptionname[[Description]] 值。
    2. 如果 descriptionundefined, 将 name 设置为空字符串。
    3. 否则,将 name 设置为 字符串连接, 包含 "["description"]"
  3. 否则,如果 name 是一个 私有名称,则
    1. name 设置为 name[[Description]]
  4. 如果 F 有一个 [[InitialName]] 内部槽,则
    1. F.[[InitialName]] 设置为 name
  5. 如果 prefix 存在,则
    1. name 设置为 字符串连接, 包含 prefix、代码单元 0x0020(空格)和 name
    2. 如果 F 有一个 [[InitialName]] 内部槽,则
      1. 可选地,将 F.[[InitialName]] 设置为 name
  6. 执行 ! DefinePropertyOrThrow(F, "name",属性描述符 { [[Value]]: name, [[Writable]]: false[[Enumerable]]: false[[Configurable]]: true }).
  7. 返回 unused

10.2.10 SetFunctionLength ( F, length )

抽象操作 SetFunctionLength 接受两个参数:F(一个 函数对象)和 length(一个非负的 整数 或 +∞),并返回 unused。它将一个 "length" 属性添加到 F 上。它在调用时执行以下步骤:

  1. 断言: F 是一个可扩展的对象,并且没有 "length" 自有属性。
  2. 执行 ! DefinePropertyOrThrow(F, "length",属性描述符 { [[Value]]: 𝔽(length), [[Writable]]: false[[Enumerable]]: false[[Configurable]]: true }).
  3. 返回 unused

10.2.11 FunctionDeclarationInstantiation ( func, argumentsList )

抽象操作 FunctionDeclarationInstantiation 接受两个参数:func(一个 ECMAScript 函数对象)和 argumentsList(一个 列表,其中包含 ECMAScript 语言值),并返回一个 正常完成 包含 unused 或一个 突然完成func 是为其建立 执行上下文 的函数对象。

注释 1

当为评估 ECMAScript 函数建立执行上下文时,会创建一个新的 函数环境记录, 并在该 环境记录 中实例化每个形式参数的绑定。 函数体中的每个声明也会被实例化。如果函数的形式参数没有包含任何默认值初始化器,则函数体中的声明会在与参数相同的 环境记录 中实例化。如果存在默认值参数初始化器,则为函数体声明创建第二个 环境记录。形式参数和函数会在 FunctionDeclarationInstantiation 过程中初始化。所有其他绑定则在函数体评估期间初始化。

它在调用时执行以下步骤:

  1. calleeContext正在执行的执行上下文
  2. codefunc.[[ECMAScriptCode]]
  3. strictfunc.[[Strict]]
  4. formalsfunc.[[FormalParameters]]
  5. parameterNames绑定名称formals
  6. 如果 parameterNames 有任何重复项,令 hasDuplicatestrue。否则,令 hasDuplicatesfalse
  7. simpleParameterList简单参数列表formals
  8. hasParameterExpressions包含表达式formals
  9. varNames变量声明名称code
  10. varDeclarations变量作用域声明code
  11. lexicalNames词法声明名称code
  12. functionNames 是一个新的空的 列表
  13. functionsToInitialize 是一个新的空的 列表
  14. 对于 varDeclarations 的每一个元素 d, 按照反向 列表 顺序,执行以下操作
    1. 如果 d 既不是 变量声明 也不是 ForBinding 也不是 BindingIdentifier,则
      1. 断言: d 要么是 函数声明, 要么是 生成器声明, 要么是 异步函数声明, 要么是 异步生成器声明
      2. fn绑定名称 的唯一元素。
      3. 如果 functionNames 不包含 fn,则
        1. fn 插入到 functionNames 的第一个位置。
        2. 注: 如果有多个相同名称的函数声明,将使用最后一个声明。
        3. d 插入到 functionsToInitialize 的第一个位置。
  15. argumentsObjectNeededtrue
  16. 如果 func.[[ThisMode]]lexical,则
    1. 注: 箭头函数永远没有 arguments 对象。
    2. argumentsObjectNeeded 设置为 false
  17. 否则,如果 parameterNames 包含 "arguments",则
    1. argumentsObjectNeeded 设置为 false
  18. 否则,如果 hasParameterExpressionsfalse,则
    1. 如果 functionNames 包含 "arguments"lexicalNames 包含 "arguments",则
      1. argumentsObjectNeeded 设置为 false
  19. 如果 stricttruehasParameterExpressionsfalse,则
    1. 注: 只需要一个 环境记录 来处理参数,因为在 eval 中的调用在 严格模式代码 中不能 创建在 eval 外部可见的新绑定。
    2. envcalleeContext 的 词法环境。
  20. 否则,
    1. 注: 需要一个单独的 环境记录 以确保由 直接 eval 调用在形式参数列表中创建的绑定在参数声明的环境之外。
    2. calleeEnvcalleeContext 的 词法环境。
    3. envNewDeclarativeEnvironment(calleeEnv)。
    4. 断言: calleeContext 的变量环境是 calleeEnv
    5. calleeContext 的词法环境设置为 env
  21. 对于 parameterNames 中的每个字符串 paramName,执行
    1. alreadyDeclared 为 ! env.HasBinding(paramName)。
    2. 注: 早期错误 确保重复的参数名称只能出现在 非严格模式函数 中,并且这些函数没有参数默认值或剩余参数。
    3. 如果 alreadyDeclaredfalse,则
      1. 执行 ! env.CreateMutableBinding(paramName, false)。
      2. 如果 hasDuplicatestrue,则
        1. 执行 ! env.InitializeBinding(paramName, undefined)。
  22. 如果 argumentsObjectNeededtrue,则
    1. 如果 stricttruesimpleParameterListfalse,则
      1. aoCreateUnmappedArgumentsObject(argumentsList)。
    2. 否则,
      1. 注: 映射的参数对象仅在 非严格模式函数 中提供,并且这些函数没有剩余参数、参数默认值初始化器或任何解构参数。
      2. aoCreateMappedArgumentsObject(func, formals, argumentsList, env)。
    3. 如果 stricttrue,则
      1. 执行 ! env.CreateImmutableBinding("arguments", false)。
      2. 注: 在 严格模式代码 中,早期错误 防止尝试对该绑定进行赋值,因此其可变性不可观察。
    4. 否则,
      1. 执行 ! env.CreateMutableBinding("arguments", false)。
    5. 执行 ! env.InitializeBinding("arguments", ao)。
    6. parameterBindingslist-concatenationparameterNames 和 « "arguments" »。
  23. 否则,
    1. parameterBindingsparameterNames
  24. iteratorRecordCreateListIteratorRecord(argumentsList)。
  25. 如果 hasDuplicatestrue,则
    1. 执行 ? IteratorBindingInitializationformals,使用参数 iteratorRecordundefined
  26. 否则,
    1. 执行 ? IteratorBindingInitializationformals,使用参数 iteratorRecordenv
  27. 如果 hasParameterExpressionsfalse,则
    1. 注: 仅需要一个 环境记录 来处理参数和顶级变量。
    2. instantiatedVarNames列表 parameterBindings 的副本。
    3. 对于 varNames 中的每个元素 n,执行
      1. 如果 instantiatedVarNames 不包含 n,则
        1. n 添加到 instantiatedVarNames
        2. 执行 ! env.CreateMutableBinding(n, false)。
        3. 执行 ! env.InitializeBinding(n, undefined)。
    4. varEnvenv
  28. 否则,
    1. 注: 需要一个单独的 环境记录 来确保在形式参数列表中创建的闭包无法访问函数体中的声明。
    2. varEnvNewDeclarativeEnvironment(env)。
    3. calleeContext 的 VariableEnvironment 设置为 varEnv
    4. instantiatedVarNames 为一个新的空 列表
    5. 对于 varNames 中的每个元素 n,执行
      1. 如果 instantiatedVarNames 不包含 n,则
        1. n 添加到 instantiatedVarNames
        2. 执行 ! varEnv.CreateMutableBinding(n, false)。
        3. 如果 parameterBindings 不包含 n,或 functionNames 包含 n,则
          1. initialValueundefined
        4. 否则,
          1. initialValue 为 ! env.GetBindingValue(n, false)。
        5. 执行 ! varEnv.InitializeBinding(n, initialValue)。
        6. 注: 与形式参数同名的变量最初具有与相应初始化参数相同的值。
  29. 注: 附录 B.3.2.1 在此处添加了额外的步骤。
  30. 如果 strictfalse,则
    1. lexEnvNewDeclarativeEnvironment(varEnv)。
    2. 注: 非严格模式函数 使用单独的 环境记录 处理顶级词法声明,以便 直接 eval 可以确定 eval 代码引入的任何 var 范围声明是否与已有的顶级词法范围声明冲突。对于 严格模式函数 不需要这样做,因为严格模式 直接 eval 总是将所有声明放入新的 环境记录
  31. 否则,
    1. lexEnvvarEnv
  32. calleeContext 的 LexicalEnvironment 设置为 lexEnv
  33. lexDeclarations词法作用域声明code
  34. 对于 lexDeclarations 中的每个元素 d,执行
    1. 注: 词法声明的名称不能与函数/生成器声明、形式参数或 var 名称相同。词法声明的名称仅在此处实例化,但不初始化。
    2. 对于 d绑定名称 中的每个元素 dn,执行
      1. 如果 是常量声明dtrue,则
        1. 执行 ! lexEnv.CreateImmutableBinding(dn, true)。
      2. 否则,
        1. 执行 ! lexEnv.CreateMutableBinding(dn, false)。
  35. privateEnvcalleeContext 的 PrivateEnvironment。
  36. 对于 functionsToInitialize 中的每个 解析节点 f,执行
    1. fnf绑定名称 的唯一元素。
    2. fo实例化函数对象f,参数为 lexEnvprivateEnv
    3. 执行 ! varEnv.SetMutableBinding(fn, fo, false)。
  37. 返回 unused
注释 2

B.3.2 提供了上述算法的扩展,以确保与早于 ECMAScript 2015 的 web 浏览器实现的向后兼容性。

10.3 内置函数对象

内置的 函数对象 是一个 普通对象;它必须满足 普通对象10.1 中规定的要求。

除了每个 普通对象 所需的内部插槽(见 10.1),内置的 函数对象 还必须具有以下内部插槽:

  • [[Realm]],一个 Realm 记录,表示创建该函数的 realm
  • [[InitialName]],一个字符串,表示函数的初始名称。它由 20.2.3.5 使用。

内置 函数对象[[Prototype]] 内部插槽的初始值是 %Function.prototype%,除非另有说明。

内置 函数对象 必须具有一个符合 10.3.1 中定义的 [[Call]] 内部方法。

内置 函数对象 仅在被描述为“构造函数”时,或某些算法在本规范中明确设置其 [[Construct]] 内部方法时,才具有 [[Construct]] 内部方法。这样的 [[Construct]] 内部方法必须符合 10.3.2 中定义的。

实现可以提供本规范中未定义的额外内置 函数对象

10.3.1 [[Call]] ( thisArgument, argumentsList )

内置 函数对象 F[[Call]] 内部方法接受参数 thisArgument(一个 ECMAScript 语言值)和 argumentsList(一个 列表ECMAScript 语言值),并返回一个正常完成记录(包含一个 ECMAScript 语言值)或一个抛出完成记录。

  1. 返回 ? BuiltinCallOrConstruct(F, thisArgument, argumentsList, undefined).

10.3.2 [[Construct]] ( argumentsList, newTarget )

内置 函数对象 F[[Construct]] 内部方法(当该方法存在时)接受参数 argumentsList(一个 列表ECMAScript 语言值)和 newTarget(一个 构造函数),并返回一个正常完成记录(包含一个对象)或一个抛出完成记录。

  1. 返回 ? BuiltinCallOrConstruct(F, uninitialized, argumentsList, newTarget).

10.3.3 BuiltinCallOrConstruct ( F, thisArgument, argumentsList, newTarget )

抽象操作 BuiltinCallOrConstruct 接受以下参数:F(一个内置的 函数对象)、thisArgument(一个 ECMAScript 语言值uninitialized)、argumentsList(一个 列表ECMAScript 语言值)、以及 newTarget(一个 构造函数undefined)。它返回一个正常完成记录(包含一个 ECMAScript 语言值)或一个抛出完成记录。调用时执行以下步骤:

  1. callerContext 为当前 运行中的执行上下文
  2. 如果 callerContext 尚未被挂起,则挂起 callerContext
  3. calleeContext 为一个新的 执行上下文
  4. calleeContext 的函数设置为 F
  5. calleeRealmF.[[Realm]]
  6. calleeContextRealm 设置为 calleeRealm
  7. calleeContext 的 ScriptOrModule 设置为 null
  8. 执行对 calleeContext 的任何必要的 实现定义 初始化。
  9. calleeContext 推入 执行上下文栈calleeContext 现在是 运行中的执行上下文
  10. result完成记录,即以符合 F 规范的方式评估 F 的结果。如果 thisArgumentuninitialized,则 this 的值为未初始化;否则,thisArgument 提供 this 值。argumentsList 提供命名参数。newTarget 提供 NewTarget 值。
  11. 注:如果 F 在本文件中定义,“F 的规范”是通过算法步骤或其他方式指定的行为。
  12. 执行上下文栈 中移除 calleeContext,并将 callerContext 恢复为 运行中的执行上下文
  13. 返回 ? result
Note

calleeContext执行上下文栈 中移除时,如果它已经被挂起并被一个可访问的生成器保留以备后续恢复,则不得销毁。

10.3.4 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList [ , realm [ , prototype [ , prefix ] ] ] )

抽象操作 CreateBuiltinFunction 接受以下参数:behaviour(一个 抽象闭包、一组算法步骤,或本规范中定义的其他函数行为)、length(一个非负的 整数 或 +∞)、name(一个 属性键 或一个 私有名称)、以及 additionalInternalSlotsList(一个 列表,包含内部槽的名称),和可选参数 realm(一个 Realm 记录)、prototype(一个对象或 null),以及 prefix(一个字符串)。该操作返回一个 函数对象additionalInternalSlotsList 包含必须作为对象的一部分定义的额外内部槽的名称。此操作创建一个内置的 函数对象。它执行以下步骤:

  1. 如果 realm 不存在,则将 realm 设置为 当前 Realm 记录
  2. 如果 prototype 不存在,则将 prototype 设置为 realm.[[Intrinsics]].[[%Function.prototype%]]。
  3. internalSlotsList 为一个 列表,包含所有 10.3 对于即将创建的内置 函数对象 所需的内部槽的名称。
  4. additionalInternalSlotsList 的元素附加到 internalSlotsList
  5. func 为一个新的内置 函数对象,当调用时,它会根据 behaviour 的描述,使用提供的参数作为 behaviour 指定的相应参数的值。新的 函数对象 具有名称为 internalSlotsList 元素的内部槽,并具有一个 [[InitialName]] 内部槽。
  6. func.[[Prototype]] 设置为 prototype
  7. func.[[Extensible]] 设置为 true
  8. func.[[Realm]] 设置为 realm
  9. func.[[InitialName]] 设置为 null
  10. 执行 SetFunctionLength(func, length)。
  11. 如果 prefix 不存在,则
    1. 执行 SetFunctionName(func, name)。
  12. 否则,
    1. 执行 SetFunctionName(func, name, prefix)。
  13. 返回 func

本规范中定义的每个内置函数都是通过调用 CreateBuiltinFunction 抽象操作创建的。

10.4 内置的奇异对象内部方法和槽

本规范定义了几种内置的 奇异对象。这些对象的行为通常类似于 普通对象,但在一些特定情况下有所不同。以下 奇异对象 使用 普通对象 的内部方法,除非在下文中明确另有说明:

10.4.1 绑定函数奇异对象

绑定函数奇异对象 是一种 奇异对象,它封装了另一个 函数对象。一个 绑定函数奇异对象 是可调用的(它有一个 [[Call]] 内部方法,并且可能有一个 [[Construct]] 内部方法)。调用一个 绑定函数奇异对象 通常会调用它封装的函数。

一个对象是一个 绑定函数奇异对象,如果它的 [[Call]] 和(如果适用的话)[[Construct]] 内部方法使用以下实现,并且它的其他基本内部方法使用在 10.1 中找到的定义。这些方法是在 BoundFunctionCreate 中安装的。

绑定函数奇异对象 不具有 ECMAScript 函数对象 中列出的内部槽,这些槽在 表30 中列出。相反,它们具有 表31 中列出的内部槽,此外还有 [[Prototype]][[Extensible]]

表31:绑定函数奇异对象的内部槽
内部槽 类型 描述
[[BoundTargetFunction]] 可调用的对象 封装的 函数对象
[[BoundThis]] 一个 ECMAScript 语言值 在调用封装的函数时始终传递的 this 值。
[[BoundArguments]] 一个 列表ECMAScript 语言值 一个值的列表,其元素作为对封装函数的任何调用的第一个参数。

10.4.1.1 [[Call]] ( thisArgument, argumentsList )

[[Call]] 内部方法用于一个 绑定函数奇异对象 F,它接受参数 thisArgument(一个 ECMAScript 语言值)和 argumentsList(一个 列表ECMAScript 语言值),并返回一个包含 ECMAScript 语言值正常完成记录,或者一个 抛出完成记录。它在被调用时执行以下步骤:

  1. targetF.[[BoundTargetFunction]]
  2. boundThisF.[[BoundThis]]
  3. boundArgsF.[[BoundArguments]]
  4. args列表连接boundArgsargumentsList
  5. 返回 ? Call(target, boundThis, args)。

10.4.1.2 [[Construct]] ( argumentsList, newTarget )

[[Construct]] 内部方法用于一个 绑定函数奇异对象 F,它接受参数 argumentsList(一个 列表ECMAScript 语言值)和 newTarget(一个 构造函数),并返回一个包含 Object 的 正常完成记录,或者一个 抛出完成记录。它在被调用时执行以下步骤:

  1. targetF.[[BoundTargetFunction]]
  2. 断言: IsConstructor(target) 为 true
  3. boundArgsF.[[BoundArguments]]
  4. args列表连接boundArgsargumentsList
  5. 如果 SameValue(F, newTarget) 为 true,则将 newTarget 设置为 target
  6. 返回 ? Construct(target, args, newTarget)。

10.4.1.3 BoundFunctionCreate ( targetFunction, boundThis, boundArgs )

抽象操作 BoundFunctionCreate 接受参数 targetFunction(一个 函数对象)、boundThis(一个 ECMAScript 语言值)和 boundArgs(一个 列表ECMAScript 语言值),并返回一个包含函数对象的 正常完成记录,或者一个 抛出完成记录。它用于指定创建新的 绑定函数奇异对象。它在被调用时执行以下步骤:

  1. proto 为 ? targetFunction.[[GetPrototypeOf]]()。
  2. internalSlotsList 为 «[[Prototype]][[Extensible]]» 和在 表 31 中列出的内部槽的 列表连接
  3. objMakeBasicObject(internalSlotsList)。
  4. obj.[[Prototype]] 设置为 proto
  5. obj.[[Call]] 设置为在 10.4.1.1 中描述的内容。
  6. 如果 IsConstructor(targetFunction) 为 true,则:
    1. obj.[[Construct]] 设置为在 10.4.1.2 中描述的内容。
  7. obj.[[BoundTargetFunction]] 设置为 targetFunction
  8. obj.[[BoundThis]] 设置为 boundThis
  9. obj.[[BoundArguments]] 设置为 boundArgs
  10. 返回 obj

10.4.2 数组奇异对象

数组是一个 奇异对象,它对 数组索引 属性键 给予特殊处理(见 6.1.7)。一个属性的 属性名 是一个 数组索引 时,这个属性也被称为 元素。每个数组都有一个不可配置的 "length" 属性,其值始终是一个非负的 整数,其 数学值 严格小于 232"length" 属性的值在数值上大于每个其名称为 数组索引 的自身属性的名称;每当创建或改变数组的自身属性时,会根据需要调整其他属性以保持这一不变性。具体来说,每当添加一个名称为 数组索引 的自身属性时,"length" 属性的值会被必要地更改为比该 数组索引 的数值大 1;并且每当 "length" 属性的值被更改时,每个其名称为 数组索引 的自身属性,其值不小于新长度时都会被删除。这一约束仅适用于数组的自身属性,不受可能从其原型继承的 "length"数组索引 属性的影响。

一个对象是一个 数组奇异对象(或简称为数组),如果它的 [[DefineOwnProperty]] 内部方法使用以下实现,并且它的其他基本内部方法使用在 10.1 中找到的定义。这些方法被安装在 ArrayCreate 中。

10.4.2.1 [[DefineOwnProperty]] ( P, Desc )

[[DefineOwnProperty]] 内部方法在 数组 奇异对象 A 中接受参数 P(一个 属性键)和 Desc (一个 属性描述符),并返回 一个 正常完成记录,其中包含 一个布尔值或一个 抛出完成记录。调用时,它 执行以下步骤:

  1. 如果 P"length",则
    1. 返回 ? ArraySetLength(A, Desc).
  2. 否则,如果 P 是一个 数组索引,则
    1. lengthDescOrdinaryGetOwnProperty(A, "length").
    2. Assert: IsDataDescriptor(lengthDesc) 是 true
    3. Assert: lengthDesc.[[Configurable]]false
    4. lengthlengthDesc.[[Value]]
    5. Assert: length 是一个非负的 整数
    6. index 为 ! ToUint32(P)。
    7. 如果 indexlengthlengthDesc.[[Writable]]false,则返回 false
    8. succeeded 为 ! OrdinaryDefineOwnProperty(A, P, Desc)。
    9. 如果 succeededfalse,则返回 false
    10. 如果 indexlength,则
      1. lengthDesc.[[Value]] 设置为 index + 1𝔽
      2. succeeded 设置为 ! OrdinaryDefineOwnProperty(A, "length", lengthDesc)。
      3. Assert: succeededtrue
    11. 返回 true
  3. 返回 ? OrdinaryDefineOwnProperty(A, P, Desc)。

10.4.2.2 ArrayCreate ( length [ , proto ] )

抽象操作 ArrayCreate 接受参数 length(一个非负的 整数) 和一个可选参数 proto(一个对象),并返回一个 正常完成记录,其中包含 一个 数组奇异对象 或一个 抛出完成记录。它用于指定创建新的数组。调用时,它执行以下步骤:

  1. 如果 length > 232 - 1,抛出一个 RangeError 异常。
  2. 如果 proto 不存在,将 proto 设置为 %Array.prototype%
  3. AMakeBasicObject[[Prototype]], [[Extensible]] »)。
  4. A.[[Prototype]] 设置为 proto
  5. A.[[DefineOwnProperty]] 设置为在 10.4.2.1 中规定的方式。
  6. 执行 ! OrdinaryDefineOwnProperty(A, "length", 属性描述符 { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  7. 返回 A

10.4.2.3 ArraySpeciesCreate ( originalArray, length )

抽象操作 ArraySpeciesCreate 接受两个参数:originalArray(一个对象)和 length(一个非负的 整数),并返回一个对象,可能是 正常完成记录,也可能是一个 抛出完成记录。它用于指定使用从 originalArray 派生的 构造函数 创建一个新的数组或类似对象。它并不强制 构造函数 函数返回一个数组。调用时,它执行以下步骤:

  1. isArray 为 ? IsArray(originalArray)。
  2. 如果 isArrayfalse,返回 ? ArrayCreate(length)。
  3. C 为 ? Get(originalArray, "constructor")。
  4. 如果 IsConstructor(C) 为 true,则
    1. thisRealm当前 Realm 记录
    2. realmC 为 ? GetFunctionRealm(C)。
    3. 如果 thisRealmrealmC 不是同一个 Realm 记录,则
      1. 如果 SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) 为 true,则将 C 设置为 undefined
  5. 如果 C 是一个对象,则
    1. C 设置为 ? Get(C, @@species)。
    2. 如果 Cnull,将 C 设置为 undefined
  6. 如果 Cundefined,返回 ? ArrayCreate(length)。
  7. 如果 IsConstructor(C) 为 false,抛出一个 TypeError 异常。
  8. 返回 ? Construct(C, « 𝔽(length)  »)。

如果 originalArray 是使用标准内置 Array 构造函数 创建的,并且它的 Realm运行时执行上下文Realm 不同,则在 运行时执行上下文Realm 中创建一个新的 Array。这保持了与历史上在使用 ArraySpeciesCreate 定义的 Array.prototype 方法时的浏览器兼容性。

10.4.2.4 ArraySetLength ( A, Desc )

抽象操作 ArraySetLength 接受两个参数:A(一个数组)和 Desc(一个 属性描述符),并返回一个 正常完成记录,包含一个布尔值,或者一个 抛出完成记录。调用时,它执行以下步骤:

  1. 如果 Desc 没有 [[Value]] 字段,则
    1. 返回 ! OrdinaryDefineOwnProperty(A, "length", Desc).
  2. newLenDescDesc 的一个副本。
  3. newLen 为 ? ToUint32(Desc.[[Value]])。
  4. numberLen 为 ? ToNumber(Desc.[[Value]])。
  5. 如果 SameValueZero(newLen, numberLen) 为 false,则抛出一个 RangeError 异常。
  6. newLenDesc.[[Value]] 设置为 newLen
  7. oldLenDesc 为 ? OrdinaryGetOwnProperty(A, "length")。
  8. AssertIsDataDescriptor(oldLenDesc) 为 true
  9. AssertoldLenDesc.[[Configurable]]false
  10. oldLenoldLenDesc.[[Value]]
  11. 如果 newLenoldLen,则
    1. 返回 ! OrdinaryDefineOwnProperty(A, "length", newLenDesc).
  12. 如果 oldLenDesc.[[Writable]]false,返回 false
  13. 如果 newLenDesc 没有 [[Writable]] 字段,或者 newLenDesc.[[Writable]]true,则
    1. newWritabletrue
  14. 否则,
    1. 注意:将 [[Writable]] 属性设置为 false 是延迟的,以防某些元素无法被删除。
    2. newWritablefalse
    3. newLenDesc.[[Writable]] 设置为 true
  15. succeeded 为 ! OrdinaryDefineOwnProperty(A, "length", newLenDesc)。
  16. 如果 succeededfalse,则返回 false
  17. 对于 A 中每个拥有的 属性键 P,其中 P 是一个 数组索引,并且 ! ToUint32(P) ≥ newLen,按降序数字索引顺序,执行
    1. deleteSucceeded 为 ! A.[[Delete]](P)。
    2. 如果 deleteSucceededfalse,则
      1. newLenDesc.[[Value]] 设置为 ! ToUint32(P) + 1𝔽
      2. 如果 newWritablefalse,则将 newLenDesc.[[Writable]] 设置为 false
      3. 执行 ! OrdinaryDefineOwnProperty(A, "length", newLenDesc)。
      4. 返回 false
  18. 如果 newWritablefalse,则
    1. succeeded 设置为 ! OrdinaryDefineOwnProperty(A, "length", 属性描述符 { [[Writable]]false } )。
    2. Assertsucceededtrue
  19. 返回 true
注意

在步骤 34 中,如果 Desc.[[Value]] 是一个对象,则其 valueOf 方法会被调用两次。这是从本规范第2版开始规定的遗留行为。

10.4.3 字符串奇异对象

字符串对象是一个封装了字符串值的 奇异对象,它暴露出虚拟的 整数索引 数据属性 对应于字符串值的每个代码单元元素。字符串奇异对象 总是有一个名为 "length"数据属性,其值是封装的字符串值的长度。 这些代码单元数据属性和 "length" 属性都是不可写的且不可配置的。

如果一个对象的 [[GetOwnProperty]][[DefineOwnProperty]][[OwnPropertyKeys]] 内部方法使用以下实现,并且它的其他基本内部方法使用在 10.1 中找到的定义, 那么该对象就是一个 字符串奇异对象 (或简称字符串对象)。这些方法被安装在 StringCreate 中。

字符串奇异对象 拥有与 普通对象 相同的内部插槽。它们还有一个 [[StringData]] 内部插槽。

10.4.3.1 [[GetOwnProperty]] ( P )

一个 字符串奇异对象 S[[GetOwnProperty]] 内部方法接收一个参数 P(一个 属性键),并返回一个 正常完成,其中包含一个 属性描述符undefined。它在被调用时执行以下步骤:

  1. descOrdinaryGetOwnProperty(S, P).
  2. 如果 desc 不为 undefined,则返回 desc
  3. 返回 StringGetOwnProperty(S, P).

10.4.3.2 [[DefineOwnProperty]] ( P, Desc )

一个 字符串奇异对象 S[[DefineOwnProperty]] 内部方法接收两个参数:P(一个 属性键)和 Desc(一个 属性描述符),并返回一个 正常完成,其中包含一个布尔值。它在被调用时执行以下步骤:

  1. stringDescStringGetOwnProperty(S, P).
  2. 如果 stringDesc 不为 undefined,则:
    1. extensibleS.[[Extensible]]
    2. 返回 IsCompatiblePropertyDescriptor(extensible, Desc, stringDesc).
  3. 返回 ! OrdinaryDefineOwnProperty(S, P, Desc).

10.4.3.3 [[OwnPropertyKeys]] ( )

一个 字符串奇异对象 O[[OwnPropertyKeys]] 内部方法不接受任何参数,并返回一个 正常完成,其中包含一个 属性键列表。它在被调用时执行以下步骤:

  1. keys 为一个新的空 列表
  2. strO.[[StringData]]
  3. 断言: str 是一个字符串
  4. lenstr 的长度。
  5. 对每一个整数 i,使得 0 ≤ i < len,按升序执行:
    1. 将 ! ToString(𝔽(i)) 追加到 keys
  6. O 的每一个自有属性键 P,使得 P 是一个 数组索引 并且 ! ToIntegerOrInfinity(P) ≥ len,按升序的数字索引顺序执行:
    1. P 追加到 keys
  7. O 的每一个自有属性键 P,使得 P 是一个 字符串 并且 P 不是一个 数组索引,按属性创建的时间顺序执行:
    1. P 追加到 keys
  8. O 的每一个自有属性键 P,使得 P 是一个 符号,按属性创建的时间顺序执行:
    1. P 追加到 keys
  9. 返回 keys

10.4.3.4 StringCreate ( value, prototype )

抽象操作 StringCreate 接受两个参数:value(一个字符串)和 prototype(一个对象),并返回一个 字符串奇异对象。它用于指定新 字符串奇异对象 的创建。它在调用时执行以下步骤:

  1. SMakeBasicObject[[Prototype]], [[Extensible]], [[StringData]] »)。
  2. S.[[Prototype]] 设置为 prototype
  3. S.[[StringData]] 设置为 value
  4. S.[[GetOwnProperty]] 设置为 10.4.3.1 中指定的内容。
  5. S.[[DefineOwnProperty]] 设置为 10.4.3.2 中指定的内容。
  6. S.[[OwnPropertyKeys]] 设置为 10.4.3.3 中指定的内容。
  7. lengthvalue 的长度。
  8. 执行 ! DefinePropertyOrThrow(S, "length", 属性描述符 { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。
  9. 返回 S

10.4.3.5 StringGetOwnProperty ( S, P )

抽象操作 StringGetOwnProperty 接受两个参数:S(一个具有 [[StringData]] 内部槽的对象)和 P(一个 属性键),并返回一个 属性描述符undefined。它在调用时执行以下步骤:

  1. 如果 P 不是一个字符串,返回 undefined
  2. indexCanonicalNumericIndexString(P)。
  3. 如果 indexundefined,返回 undefined
  4. 如果 IsIntegralNumber(index) 是 false,返回 undefined
  5. 如果 index-0𝔽,返回 undefined
  6. strS.[[StringData]]
  7. Assert: str 是一个字符串
  8. lenstr 的长度。
  9. 如果 (index) < 0 或 len(index),返回 undefined
  10. resultStrstr(index) 到 (index) + 1 的子字符串。
  11. 返回属性描述符 { [[Value]]: resultStr, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }。

10.4.4 Arguments Exotic Objects

大多数 ECMAScript 函数会向其代码提供一个 arguments 对象。根据函数定义的特性,其 arguments 对象可能是一个 普通对象arguments 特殊对象。一个 arguments 特殊对象 是一种 特殊对象,其 数组索引 属性映射到其关联 ECMAScript 函数的正式参数绑定。

如果一个对象的内部方法使用以下实现(未在此处指定的使用 10.1 中找到的实现),则该对象是一个 arguments 特殊对象。这些方法由 CreateMappedArgumentsObject 安装。

Note 1

虽然 CreateUnmappedArgumentsObject 被归入本条款,但它创建的是一个 普通对象,而不是一个 arguments 特殊对象

Arguments 特殊对象 具有与 普通对象 相同的内部槽。它们还具有一个 [[ParameterMap]] 内部槽。普通 arguments 对象也具有一个 [[ParameterMap]] 内部槽,其值始终为 undefined。对于普通 arguments 对象,[[ParameterMap]] 内部槽仅由 Object.prototype.toString (20.1.3.6) 用于识别它们。

Note 2

一个 整数索引 数据属性arguments 特殊对象 的数字名称值小于 相应 函数对象 的正式参数数量时,初始时它们的值与函数的 执行上下文 中相应的参数绑定共享。这 意味着,改变属性会改变相应的参数绑定的值,反之亦然。如果删除该属性后重新定义它,或者如果该属性被改变为 存取属性,则这种对应关系会中断。如果 arguments 对象是一个 普通对象,则其属性的值仅是传递给函数的参数的副本,属性值与正式参数值之间没有动态关联。

Note 3

ParameterMap 对象及其属性值用作指定 arguments 对象与参数绑定之间对应关系的设备。ParameterMap 对象及其属性值并不直接从 ECMAScript 代码中可观察。ECMAScript 实现不需要实际创建或使用此类对象来实现指定的语义。

Note 4

普通 arguments 对象定义了一个不可配置的 存取属性,其名称为 "callee",在访问时会抛出 TypeError 异常。对于 arguments 特殊对象"callee" 属性具有更具体的意义,这些对象仅为某些 非严格模式函数 创建。普通变体中的该属性定义存在是为了确保符合 ECMAScript 规范的实现不会以其他方式定义该属性。

Note 5

ECMAScript 对 arguments 特殊对象 的实现历史上包含了一个名为 "caller"存取属性。在 ECMAScript 2017 之前,规范中包括了在普通 arguments 对象上定义一个抛出异常的 "caller" 属性。由于实现不再包含此扩展,ECMAScript 2017 删除了对抛出异常的 "caller" 存取器的要求。

10.4.4.1 [[GetOwnProperty]] ( P )

[[GetOwnProperty]] 内部方法用于 arguments 特殊对象 args,接受一个参数 P(一个 属性键),并 返回一个 正常完成记录,该记录包含 一个 属性描述符undefined。当调用时,它执行以下步骤:

  1. descOrdinaryGetOwnProperty(args, P)。
  2. 如果 descundefined,则返回 undefined
  3. mapargs.[[ParameterMap]]
  4. isMapped 为 ! HasOwnProperty(map, P)。
  5. 如果 isMappedtrue,则
    1. desc.[[Value]] 设置为 ! Get(map, P)。
  6. 返回 desc

10.4.4.2 [[DefineOwnProperty]] ( P, Desc )

[[DefineOwnProperty]] 内部方法用于 arguments 特殊对象 args,接受两个参数:P(一个 属性键)和 Desc(一个 属性描述符),并 返回一个 正常完成记录,该记录 包含一个布尔值。调用时,它执行以下步骤:

  1. mapargs.[[ParameterMap]]
  2. isMapped 为 ! HasOwnProperty(map, P)。
  3. newArgDescDesc
  4. 如果 isMappedtrueIsDataDescriptor(Desc) 为 true,则
    1. 如果 Desc 没有 [[Value]] 字段,Desc 有一个 [[Writable]] 字段,且 Desc.[[Writable]]false,则
      1. newArgDesc 设置为 Desc 的副本。
      2. newArgDesc.[[Value]] 设置为 ! Get(map, P)。
  5. allowed 为 ! OrdinaryDefineOwnProperty(args, P, newArgDesc)。
  6. 如果 allowedfalse,则返回 false
  7. 如果 isMappedtrue,则
    1. 如果 IsAccessorDescriptor(Desc) 为 true,则
      1. 执行 ! map.[[Delete]](P)。
    2. 否则,
      1. 如果 Desc[[Value]] 字段,则
        1. Assert: 以下 Set 操作将成功,因为由 arguments 对象映射的正式参数始终是可写的。
        2. 执行 ! Set(map, P, Desc.[[Value]], false)。
      2. 如果 Desc[[Writable]] 字段且 Desc.[[Writable]]false,则
        1. 执行 ! map.[[Delete]](P)。
  8. 返回 true

10.4.4.3 [[Get]] ( P, Receiver )

[[Get]] 内部方法用于 arguments 特殊对象 args,接受两个参数: P(一个 属性键) 和 Receiver(一个 ECMAScript 语言值),并返回一个正常 完成记录,其中包含一个 ECMAScript 语言值 或一个 抛出完成。调用时,它执行以下步骤:

  1. mapargs.[[ParameterMap]]
  2. isMapped 为 ! HasOwnProperty(map, P)。
  3. 如果 isMappedfalse,则
    1. 返回 ? OrdinaryGet(args, P, Receiver)。
  4. 否则,
    1. Assertmap 包含 P 的正式参数映射。
    2. 返回 ! Get(map, P)。

10.4.4.4 [[Set]] ( P, V, Receiver )

[[Set]] 内部方法用于 arguments 特殊对象 args,接受三个参数: P(一个 属性键), V(一个 ECMAScript 语言值), 和 Receiver(一个 ECMAScript 语言值),并返回一个正常 完成记录,其中包含一个布尔值或一个 抛出完成。调用时,它执行以下步骤:

  1. 如果 SameValue(args, Receiver) 为 false,则
    1. isMappedfalse
  2. 否则,
    1. mapargs.[[ParameterMap]]
    2. isMapped 为 ! HasOwnProperty(map, P)。
  3. 如果 isMappedtrue,则
    1. Assert:以下的 Set 操作将会成功,因为 arguments 对象中的正式参数总是可写的。
    2. 执行 ! Set(map, P, V, false)。
  4. 返回 ? OrdinarySet(args, P, V, Receiver)。

10.4.4.5 [[Delete]] ( P )

[[Delete]] 内部方法用于 arguments 特殊对象 args, 接受一个参数 P(一个 属性键), 并返回一个正常完成记录,其中包含一个布尔值或一个 抛出完成。调用时,它执行以下步骤:

  1. mapargs.[[ParameterMap]]
  2. isMapped 为 ! HasOwnProperty(map, P)。
  3. result 为 ? OrdinaryDelete(args, P)。
  4. 如果 resulttrueisMappedtrue,则
    1. 执行 ! map.[[Delete]](P)。
  5. 返回 result

10.4.4.6 CreateUnmappedArgumentsObject ( argumentsList )

抽象操作 CreateUnmappedArgumentsObject 接受一个参数 argumentsList(一个 列表,包含 ECMAScript 语言值),并返回一个 普通对象。调用时,它执行以下步骤:

  1. lenargumentsList 中的元素数量。
  2. objOrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »).
  3. obj.[[ParameterMap]] 设置为 undefined
  4. 执行 ! DefinePropertyOrThrow(obj, "length", 属性描述符 { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  5. index 为 0。
  6. 重复,直到 index < len
    1. valargumentsList[index]。
    2. 执行 ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val)。
    3. index 设置为 index + 1。
  7. 执行 ! DefinePropertyOrThrow(obj, @@iterator, 属性描述符 { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  8. 执行 ! DefinePropertyOrThrow(obj, "callee", 属性描述符 { [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false }).
  9. 返回 obj

10.4.4.7 CreateMappedArgumentsObject ( func, formals, argumentsList, env )

抽象操作 CreateMappedArgumentsObject 接受参数 func(一个对象)、formals(一个 解析节点)、argumentsList(一个 列表,包含 ECMAScript 语言值)和 env(一个 环境记录),并返回一个 arguments 特殊对象。调用时执行以下步骤:

  1. 断言formals 不包含剩余参数、任何绑定模式或任何初始化器。它可以包含重复的标识符。
  2. lenargumentsList 中元素的数量。
  3. objMakeBasicObject[[Prototype]], [[Extensible]], [[ParameterMap]] »)。
  4. 设置 obj.[[GetOwnProperty]]10.4.4.1 所述。
  5. 设置 obj.[[DefineOwnProperty]]10.4.4.2 所述。
  6. 设置 obj.[[Get]]10.4.4.3 所述。
  7. 设置 obj.[[Set]]10.4.4.4 所述。
  8. 设置 obj.[[Delete]]10.4.4.5 所述。
  9. 设置 obj.[[Prototype]]%Object.prototype%
  10. mapOrdinaryObjectCreate(null)。
  11. 设置 obj.[[ParameterMap]]map
  12. parameterNamesBoundNamesformals
  13. numberOfParametersparameterNames 中元素的数量。
  14. index 为 0。
  15. 重复,直到 index < len
    1. valargumentsList[index]。
    2. 执行 ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val)。
    3. 设置 indexindex + 1。
  16. 执行 ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  17. mappedNames 为一个新的空的 列表
  18. 设置 indexnumberOfParameters - 1。
  19. 重复,直到 index ≥ 0,
    1. nameparameterNames[index]。
    2. 如果 mappedNames 不包含 name,那么
      1. name 添加到 mappedNames
      2. 如果 index < len,那么
        1. gMakeArgGetter(name, env)。
        2. pMakeArgSetter(name, env)。
        3. 执行 ! map.[[DefineOwnProperty]](! ToString(𝔽(index)), PropertyDescriptor { [[Set]]: p, [[Get]]: g, [[Enumerable]]: false, [[Configurable]]: true })。
    3. 设置 indexindex - 1。
  20. 执行 ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  21. 执行 ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })。
  22. 返回 obj

10.4.4.7.1 MakeArgGetter ( name, env )

抽象操作 MakeArgGetter 接受参数 name(一个字符串)和 env(一个 环境记录),并返回一个 函数对象。它创建一个内置的 函数对象,该函数对象在执行时返回在 env 中绑定的 name 的值。调用时执行以下步骤:

  1. getterClosure 为一个新的 抽象闭包,无参数,捕获 nameenv,并在调用时执行以下步骤:
    1. 返回 env.GetBindingValue(name, false)。
  2. getterCreateBuiltinFunction(getterClosure, 0, "", « »)。
  3. 注意:getter 从不直接被 ECMAScript 代码访问。
  4. 返回 getter

10.4.4.7.2 MakeArgSetter ( name, env )

抽象操作 MakeArgSetter 接受参数 name(一个字符串)和 env(一个 环境记录),并返回一个 函数对象。它创建一个内置的 函数对象,该函数对象在执行时设置在 env 中绑定的 name 的值。调用时执行以下步骤:

  1. setterClosure 为一个新的 抽象闭包,参数为 (value),捕获 nameenv,并在调用时执行以下步骤:
    1. 返回 ! env.SetMutableBinding(name, value, false)。
  2. setterCreateBuiltinFunction(setterClosure, 1, "", « »)。
  3. 注意:setter 从不直接被 ECMAScript 代码访问。
  4. 返回 setter

10.4.5 TypedArray 特殊对象

TypedArray 是一种 特殊对象,它对 整数索引 属性键 进行特殊处理。

TypedArrays 具有与 普通对象 相同的内部槽,并且额外具有 [[ViewedArrayBuffer]][[ArrayLength]][[ByteOffset]][[ContentType]][[TypedArrayName]] 内部槽。

如果一个对象的 [[GetOwnProperty]][[HasProperty]][[DefineOwnProperty]][[Get]][[Set]][[Delete]][[OwnPropertyKeys]] 内部方法使用本节中的定义,并且其其他基本内部方法使用 10.1 中的定义,则该对象是一个 TypedArray。这些方法由 TypedArrayCreate 安装。

10.4.5.1 [[GetOwnProperty]] ( P )

[[GetOwnProperty]]TypedArray O 的内部方法,它接受参数 P(一个 属性键),并返回一个 正常完成记录,包含 属性描述符undefined。调用时执行以下步骤:

  1. 如果 P 是一个字符串,则:
    1. numericIndexCanonicalNumericIndexString(P)。
    2. 如果 numericIndex 不是 undefined,则:
      1. valueTypedArrayGetElement(O, numericIndex)。
      2. 如果 valueundefined,则返回 undefined
      3. 返回属性描述符 { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true  }。
  2. 返回 OrdinaryGetOwnProperty(O, P)。

10.4.5.2 [[HasProperty]] ( P )

[[HasProperty]]TypedArray O 的内部方法,它接受参数 P(一个 属性键),并返回一个 正常完成记录,包含一个布尔值或一个 抛出完成记录。调用时执行以下步骤:

  1. 如果 P 是一个字符串,则:
    1. numericIndexCanonicalNumericIndexString(P)。
    2. 如果 numericIndex 不是 undefined,返回 IsValidIntegerIndex(O, numericIndex)。
  2. 返回 ? OrdinaryHasProperty(O, P)。

10.4.5.3 [[DefineOwnProperty]] ( P, Desc )

[[DefineOwnProperty]]TypedArray O 的内部方法,它接受参数 P(一个 属性键)和 Desc(一个 属性描述符),并返回一个 正常完成记录,包含一个布尔值,或者一个 抛出完成记录。调用时执行以下步骤:

  1. 如果 P 是一个字符串,则:
    1. numericIndexCanonicalNumericIndexString(P)。
    2. 如果 numericIndex 不是 undefined,则:
      1. 如果 IsValidIntegerIndex(O, numericIndex) 为 false,则返回 false
      2. 如果 Desc 具有 [[Configurable]] 字段且 Desc.[[Configurable]]false,则返回 false
      3. 如果 Desc 具有 [[Enumerable]] 字段且 Desc.[[Enumerable]]false,则返回 false
      4. 如果 IsAccessorDescriptor(Desc) 为 true,则返回 false
      5. 如果 Desc 具有 [[Writable]] 字段且 Desc.[[Writable]]false,则返回 false
      6. 如果 Desc 具有 [[Value]] 字段,执行 ? TypedArraySetElement(O, numericIndex, Desc.[[Value]])。
      7. 返回 true
  2. 返回 ! OrdinaryDefineOwnProperty(O, P, Desc)。

10.4.5.4 [[Get]] ( P, Receiver )

[[Get]]TypedArray O 的内部方法,它接受参数 P(一个 属性键)和 Receiver(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含一个 ECMAScript 语言值 或一个 抛出完成记录。调用时执行以下步骤:

  1. 如果 P 是一个字符串,则:
    1. numericIndexCanonicalNumericIndexString(P)。
    2. 如果 numericIndex 不是 undefined,则:
      1. 返回 TypedArrayGetElement(O, numericIndex)。
  2. 返回 ? OrdinaryGet(O, P, Receiver)。

10.4.5.5 [[Set]] ( P, V, Receiver )

[[Set]]TypedArray O 的内部方法,它接受参数 P(一个 属性键)、V(一个 ECMAScript 语言值)和 Receiver(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含一个布尔值,或者一个 抛出完成记录。调用时执行以下步骤:

  1. 如果 P 是一个字符串,则:
    1. numericIndexCanonicalNumericIndexString(P)。
    2. 如果 numericIndex 不是 undefined,则:
      1. 如果 SameValue(O, Receiver) 为 true,则:
        1. 执行 ? TypedArraySetElement(O, numericIndex, V)。
        2. 返回 true
      2. 如果 IsValidIntegerIndex(O, numericIndex) 为 false,则返回 true
  2. 返回 ? OrdinarySet(O, P, V, Receiver)。

10.4.5.6 [[Delete]] ( P )

[[Delete]]TypedArray O 的内部方法,它接受参数 P(一个 属性键),并返回一个 正常完成记录,包含一个布尔值。调用时执行以下步骤:

  1. 如果 P 是一个字符串,则:
    1. numericIndexCanonicalNumericIndexString(P)。
    2. 如果 numericIndex 不是 undefined,则:
      1. 如果 IsValidIntegerIndex(O, numericIndex) 为 false,则返回 true;否则返回 false
  2. 返回 ! OrdinaryDelete(O, P)。

10.4.5.7 [[OwnPropertyKeys]] ( )

[[OwnPropertyKeys]]TypedArray O 的内部方法,它不接受任何参数,并返回一个 正常完成记录,包含一个 列表,其中包含 属性键。调用时执行以下步骤:

  1. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
  2. keys 为一个新的空的 列表
  3. 如果 IsTypedArrayOutOfBounds(taRecord) 为 false,则:
    1. lengthTypedArrayLength(taRecord)。
    2. 对于每个满足 0 ≤ i < length整数 i,按升序进行:
      1. 将 ! ToString(𝔽(i)) 添加到 keys
  4. 对于每个 O 的自身 属性键 P,如果 P 是一个字符串 并且 P 不是一个 整数索引,按属性创建的时间顺序升序进行:
    1. P 添加到 keys
  5. 对于每个 O 的自身 属性键 P,如果 P 是一个符号,按属性创建的时间顺序升序进行:
    1. P 添加到 keys
  6. 返回 keys

10.4.5.8 带缓冲见证记录的 TypedArray

一个 带缓冲见证记录的 TypedArray 是一个 记录 值,用于封装一个 TypedArray 以及查看缓冲区的缓存字节长度。它用于确保当查看的缓冲区是一个 可增长的 SharedArrayBuffer 时,有一个单一的共享内存读取事件来读取字节长度数据块。

带缓冲见证记录的 TypedArray 具有 表 32 中列出的字段。

表 32: 带缓冲见证记录的 TypedArray 字段
字段名称 含义
[[Object]] 一个 TypedArray 其缓冲区的字节长度被加载的 TypedArray
[[CachedBufferByteLength]] 一个非负的 整数detached 创建 记录 时对象的 [[ViewedArrayBuffer]] 的字节长度。

10.4.5.9 MakeTypedArrayWithBufferWitnessRecord ( obj, order )

抽象操作 MakeTypedArrayWithBufferWitnessRecord 接受参数 obj(一个 TypedArray)和 orderseq-cstunordered),并返回一个 带缓冲见证记录的 TypedArray。调用时执行以下步骤:

  1. bufferobj.[[ViewedArrayBuffer]]
  2. 如果 IsDetachedBuffer(buffer) 为 true,则:
    1. byteLengthdetached
  3. 否则,
    1. byteLengthArrayBufferByteLength(buffer, order)。
  4. 返回 带缓冲见证记录的 TypedArray { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength  }。

10.4.5.10 TypedArrayCreate ( prototype )

抽象操作 TypedArrayCreate 接受参数 prototype(一个对象),并返回一个 TypedArray。它用于指定新 TypedArrays 的创建。调用时执行以下步骤:

  1. internalSlotsList 为 « [[Prototype]], [[Extensible]], [[ViewedArrayBuffer]], [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], [[ArrayLength]]  »。
  2. AMakeBasicObject(internalSlotsList)。
  3. 设置 A.[[GetOwnProperty]]10.4.5.1 中所指定的。
  4. 设置 A.[[HasProperty]]10.4.5.2 中所指定的。
  5. 设置 A.[[DefineOwnProperty]]10.4.5.3 中所指定的。
  6. 设置 A.[[Get]]10.4.5.4 中所指定的。
  7. 设置 A.[[Set]]10.4.5.5 中所指定的。
  8. 设置 A.[[Delete]]10.4.5.6 中所指定的。
  9. 设置 A.[[OwnPropertyKeys]]10.4.5.7 中所指定的。
  10. A.[[Prototype]] 设置为 prototype
  11. 返回 A

10.4.5.11 TypedArrayByteLength ( taRecord )

抽象操作 TypedArrayByteLength 接受参数 taRecord(一个 带缓冲见证记录的 TypedArray),并返回一个非负的 整数。调用时执行以下步骤:

  1. 如果 IsTypedArrayOutOfBounds(taRecord) 为 true,则返回 0。
  2. lengthTypedArrayLength(taRecord)。
  3. 如果 length = 0,则返回 0。
  4. OtaRecord.[[Object]]
  5. 如果 O.[[ByteLength]] 不为 auto,则返回 O.[[ByteLength]]
  6. elementSizeTypedArrayElementSize(O)。
  7. 返回 length × elementSize

10.4.5.12 TypedArrayLength ( taRecord )

抽象操作 TypedArrayLength 接受参数 taRecord(一个 带缓冲见证记录的 TypedArray),并返回一个非负的 整数。调用时执行以下步骤:

  1. 断言IsTypedArrayOutOfBounds(taRecord) 为 false
  2. OtaRecord.[[Object]]
  3. 如果 O.[[ArrayLength]] 不为 auto,则返回 O.[[ArrayLength]]
  4. 断言IsFixedLengthArrayBuffer(O.[[ViewedArrayBuffer]]) 为 false
  5. byteOffsetO.[[ByteOffset]]
  6. elementSizeTypedArrayElementSize(O)。
  7. byteLengthtaRecord.[[CachedBufferByteLength]]
  8. 断言byteLength 不为 detached
  9. 返回 floor((byteLength - byteOffset) / elementSize)。

10.4.5.13 IsTypedArrayOutOfBounds ( taRecord )

抽象操作 IsTypedArrayOutOfBounds 接受参数 taRecord(一个 带缓冲见证记录的 TypedArray),并返回一个布尔值。它检查对象的任何数值属性是否引用了基础缓冲区边界内不包含的索引处的值。调用时执行以下步骤:

  1. OtaRecord.[[Object]]
  2. bufferByteLengthtaRecord.[[CachedBufferByteLength]]
  3. 断言:如果 O.[[ViewedArrayBuffer]]IsDetachedBuffer,则 bufferByteLength 必须为 detached
  4. 如果 bufferByteLengthdetached,返回 true
  5. byteOffsetStartO.[[ByteOffset]]
  6. 如果 O.[[ArrayLength]]auto,则:
    1. byteOffsetEndbufferByteLength
  7. 否则,
    1. elementSizeTypedArrayElementSize(O)。
    2. byteOffsetEndbyteOffsetStart + O.[[ArrayLength]] × elementSize
  8. 如果 byteOffsetStart > bufferByteLengthbyteOffsetEnd > bufferByteLength,返回 true
  9. 注意:长度为 0 的 TypedArrays 不被视为越界。
  10. 返回 false

10.4.5.14 IsValidIntegerIndex ( O, index )

抽象操作 IsValidIntegerIndex 接受参数 O(一个 TypedArray)和 index(一个数字),并返回一个布尔值。调用时执行以下步骤:

  1. 如果 IsDetachedBuffer(O.[[ViewedArrayBuffer]]) 为 true,返回 false
  2. 如果 IsIntegralNumber(index) 为 false,返回 false
  3. 如果 index-0𝔽,返回 false
  4. taRecordMakeTypedArrayWithBufferWitnessRecord(O, unordered)。
  5. 注意:当 O 的后备缓冲区是一个 可增长的 SharedArrayBuffer 时,边界检查不是同步操作。
  6. 如果 IsTypedArrayOutOfBounds(taRecord) 为 true,返回 false
  7. lengthTypedArrayLength(taRecord)。
  8. 如果 (index) < 0 或 (index) ≥ length,返回 false
  9. 返回 true

10.4.5.15 TypedArrayGetElement ( O, index )

抽象操作 TypedArrayGetElement 接受参数 O(一个 TypedArray)和 index(一个数字),并返回一个数字、BigInt 或 undefined。调用时执行以下步骤:

  1. 如果 IsValidIntegerIndex(O, index) 为 false,返回 undefined
  2. offsetO.[[ByteOffset]]
  3. elementSizeTypedArrayElementSize(O)。
  4. byteIndexInBuffer 为 ((index) × elementSize) + offset
  5. elementTypeTypedArrayElementType(O)。
  6. 返回 GetValueFromBuffer(O.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, true, unordered)。

10.4.5.16 TypedArraySetElement ( O, index, value )

抽象操作 TypedArraySetElement 接受参数 O(一个 TypedArray)、index(一个数字)和 value(一个 ECMAScript 语言值),并返回一个 包含 unused抛出完成记录。调用时执行以下步骤:

  1. 如果 O.[[ContentType]]bigint,令 numValue 为 ? ToBigInt(value)。
  2. 否则,令 numValue 为 ? ToNumber(value)。
  3. 如果 IsValidIntegerIndex(O, index) 为 true,则:
    1. offsetO.[[ByteOffset]]
    2. elementSizeTypedArrayElementSize(O)。
    3. byteIndexInBuffer 为 ((index) × elementSize) + offset
    4. elementTypeTypedArrayElementType(O)。
    5. 执行 SetValueInBuffer(O.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, numValue, true, unordered)。
  4. 返回 unused
注意

此操作似乎总是成功,但在尝试写入 TypedArray 的末尾或写入由已分离的 ArrayBuffer 支持的 TypedArray 时没有效果。

10.4.5.17 IsArrayBufferViewOutOfBounds ( O )

抽象操作 IsArrayBufferViewOutOfBounds 接受参数 O(一个 TypedArray 或一个 DataView),并返回一个布尔值。它检查 TypedArray 的数值属性或 DataView 对象的方法是否可以引用基础数据块边界之外的索引处的值。此抽象操作存在是为了方便上游规范。调用时执行以下步骤:

  1. 如果 O 具有 [[DataView]] 内部插槽,则:
    1. viewRecordMakeDataViewWithBufferWitnessRecord(O, seq-cst)。
    2. 返回 IsViewOutOfBounds(viewRecord)。
  2. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)。
  3. 返回 IsTypedArrayOutOfBounds(taRecord)。

10.4.6 模块命名空间特殊对象

一个 模块命名空间特殊对象 是一个 特殊对象,它暴露了从 ECMAScript 模块 导出的绑定(参见 16.2.3)。一个 模块命名空间特殊对象 的字符串键自身属性与模块导出的绑定名称之间存在一一对应关系。导出的绑定包括使用 export * 语法间接导出的绑定。每个字符串值自身属性键是相应导出绑定名称的 字符串值。这些是 模块命名空间特殊对象 的唯一字符串键属性。每个这样的属性具有以下属性: { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }。模块命名空间特殊对象 是不可扩展的。

一个对象是一个 模块命名空间特殊对象,如果它的 [[GetPrototypeOf]], [[SetPrototypeOf]], [[IsExtensible]], [[PreventExtensions]], [[GetOwnProperty]], [[DefineOwnProperty]], [[HasProperty]], [[Get]], [[Set]], [[Delete]], 和 [[OwnPropertyKeys]] 内部方法使用本节中的定义,而它的其他基本内部方法使用 10.1 中的定义。这些方法由 ModuleNamespaceCreate 安装。

模块命名空间特殊对象 具有 表 33 中定义的内部插槽。

表 33:模块命名空间特殊对象的内部插槽
内部插槽名称 类型 描述
[[Module]] 一个 模块记录 暴露此命名空间导出的 模块记录
[[Exports]] 一个 字符串列表 一个 列表,其元素是作为此对象的自身属性暴露的导出名称的字符串值。该列表的顺序就像用 %Array.prototype.sort% 使用 undefined 作为 comparefn 对这些字符串值进行排序一样。

10.4.6.1 [[GetPrototypeOf]] ( )

一个 模块命名空间特殊对象[[GetPrototypeOf]] 内部方法不接收任何参数,返回一个 正常完成记录,包含 null。它执行以下步骤:

  1. 返回 null

10.4.6.2 [[SetPrototypeOf]] ( V )

一个 模块命名空间特殊对象[[SetPrototypeOf]] 内部方法接收参数 V(一个对象或 null),返回一个 正常完成记录,包含 一个布尔值。它执行以下步骤:

  1. 返回 ! SetImmutablePrototype(O, V)。

10.4.6.3 [[IsExtensible]] ( )

一个 模块命名空间特殊对象[[IsExtensible]] 内部方法不接收任何参数,返回一个 正常完成记录,包含 false。它执行以下步骤:

  1. 返回 false

10.4.6.4 [[PreventExtensions]] ( )

一个 模块命名空间特殊对象[[PreventExtensions]] 内部方法不接收任何参数,返回一个 正常完成记录,包含 true。它执行以下步骤:

  1. 返回 true

10.4.6.5 [[GetOwnProperty]] ( P )

一个 模块命名空间特殊对象[[GetOwnProperty]] 内部方法接收参数 P(一个 属性键),返回一个 正常完成记录,包含 一个 属性描述符undefined,或一个 抛出完成记录。它执行以下步骤:

  1. 如果 P 是一个符号,返回 OrdinaryGetOwnProperty(O, P)。
  2. exports 成为 O[[Exports]]
  3. 如果 exports 不包含 P,返回 undefined
  4. value 成为 ? O.[[Get]](P, O)。
  5. 返回 PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }。

10.4.6.6 [[DefineOwnProperty]] ( P, Desc )

一个 模块命名空间特殊对象[[DefineOwnProperty]] 内部方法接收参数 P(一个 属性键)和 Desc(一个 属性描述符),返回一个 正常完成记录,包含 一个布尔值或一个 抛出完成记录。它执行以下步骤:

  1. 如果 P 是一个符号,返回 ! OrdinaryDefineOwnProperty(O, P, Desc)。
  2. current 成为 ? O.[[GetOwnProperty]](P)。
  3. 如果 currentundefined,返回 false
  4. 如果 Desc 具有 [[Configurable]] 字段,并且 Desc[[Configurable]]true,返回 false
  5. 如果 Desc 具有 [[Enumerable]] 字段,并且 Desc[[Enumerable]]false,返回 false
  6. 如果 IsAccessorDescriptor(Desc) 是 true,返回 false
  7. 如果 Desc 具有 [[Writable]] 字段,并且 Desc[[Writable]]false,返回 false
  8. 如果 Desc 具有 [[Value]] 字段,返回 SameValue(Desc.[[Value]], current.[[Value]])。
  9. 返回 true

10.4.6.7 [[HasProperty]] ( P )

一个 模块命名空间特殊对象[[HasProperty]] 内部方法接收参数 P(一个 属性键),返回一个 正常完成记录,包含 一个布尔值。它执行以下步骤:

  1. 如果 P 是一个符号,返回 ! OrdinaryHasProperty(O, P)。
  2. exports 成为 O[[Exports]]
  3. 如果 exports 包含 P,返回 true
  4. 返回 false

10.4.6.8 [[Get]] ( P, Receiver )

一个 模块命名空间特殊对象[[Get]] 内部方法接收参数 P(一个 属性键)和 Receiver(一个 ECMAScript 语言值),返回一个 正常完成记录,包含 一个 ECMAScript 语言值 或一个 抛出完成记录。它执行以下步骤:

  1. 如果 P 是一个符号,则
    1. 返回 ! OrdinaryGet(O, P, Receiver)。
  2. exports 成为 O[[Exports]]
  3. 如果 exports 不包含 P,返回 undefined
  4. m 成为 O[[Module]]
  5. binding 成为 m.ResolveExport(P)。
  6. 断言binding 是一个 已解析绑定记录
  7. targetModule 成为 binding[[Module]]
  8. 断言targetModule 不是 undefined
  9. 如果 binding[[BindingName]]namespace,则
    1. 返回 GetModuleNamespace(targetModule)。
  10. targetEnv 成为 targetModule[[Environment]]
  11. 如果 targetEnvempty,抛出一个 ReferenceError 异常。
  12. 返回 ? targetEnv.GetBindingValue(binding.[[BindingName]], true)。
注意

ResolveExport 是无副作用的。每次用特定的 exportNameresolveSet 参数调用此操作时,它必须返回相同的结果。实现可以选择预先计算或缓存每个 模块命名空间特殊对象[[Exports]] 的 ResolveExport 结果。

10.4.6.9 [[Set]] ( P, V, Receiver )

一个 模块命名空间特殊对象[[Set]] 内部方法接收参数 P(一个 属性键),V(一个 ECMAScript 语言值),和 Receiver(一个 ECMAScript 语言值),返回一个 正常完成记录,包含 false。它执行以下步骤:

  1. 返回 false

10.4.6.10 [[Delete]] ( P )

一个 模块命名空间特殊对象[[Delete]] 内部方法接收参数 P(一个 属性键),返回一个 正常完成记录,包含 一个布尔值。它执行以下步骤:

  1. 如果 P 是一个符号,则
    1. 返回 ! OrdinaryDelete(O, P)。
  2. exports 成为 O[[Exports]]
  3. 如果 exports 包含 P,返回 false
  4. 返回 true

10.4.6.11 [[OwnPropertyKeys]] ( )

一个 模块命名空间特殊对象[[OwnPropertyKeys]] 内部方法不接收任何参数,返回一个 正常完成记录,包含 一个 列表属性键。它执行以下步骤:

  1. exports 成为 O[[Exports]]
  2. symbolKeys 成为 OrdinaryOwnPropertyKeys(O)。
  3. 返回 列表连接 exportssymbolKeys

10.4.6.12 ModuleNamespaceCreate ( module, exports )

抽象操作 ModuleNamespaceCreate 接收参数 module(一个 模块记录)和 exports(一个 字符串列表),返回一个 模块命名空间特殊对象。它用于指定创建新的 模块命名空间特殊对象。它执行以下步骤:

  1. 断言module[[Namespace]]empty
  2. internalSlotsList 成为 表 33 中列出的内部插槽。
  3. M 成为 MakeBasicObject(internalSlotsList)。
  4. M 的基本内部方法设置为 10.4.6 中的定义。
  5. M[[Module]] 设置为 module
  6. sortedExports 成为 列表,其元素是 exports 的元素,顺序就像用 %Array.prototype.sort% 使用 undefined 作为 comparefn 对这些值进行排序一样。
  7. M[[Exports]] 设置为 sortedExports
  8. 创建与 28.3 中定义相对应的 M 自身属性。
  9. module[[Namespace]] 设置为 M
  10. 返回 M

10.4.7 不可变原型特殊对象

一个 不可变原型特殊对象 是一个具有 [[Prototype]] 内部插槽的 特殊对象,该插槽在初始化后不会改变。

如果对象的 [[SetPrototypeOf]] 内部方法使用以下实现,则该对象是一个 不可变原型特殊对象。(其其他基本内部方法可以根据具体的 不可变原型特殊对象 使用任意实现。)

注意

与其他 特殊对象 不同,没有为 不可变原型特殊对象 提供专门的创建抽象操作。这是因为它们仅由 %Object.prototype%宿主环境 使用,并且在 宿主环境 中,相关对象可能在其他方面也是特殊的,因此需要它们自己的专门创建操作。

10.4.7.1 [[SetPrototypeOf]] ( V )

一个 不可变原型特殊对象[[SetPrototypeOf]] 内部方法接收参数 V(一个对象或 null),并返回一个 正常完成记录,包含 一个布尔值或一个 抛出完成记录。它执行以下步骤:

  1. 返回 ? SetImmutablePrototype(O, V)。

10.4.7.2 SetImmutablePrototype ( O, V )

抽象操作 SetImmutablePrototype 接收参数 O(一个对象)和 V(一个对象或 null),并返回一个 正常完成记录,包含 一个布尔值或一个 抛出完成记录。它执行以下步骤:

  1. current 成为 ? O.[[GetPrototypeOf]]()。
  2. 如果 SameValue(V, current) 是 true,返回 true
  3. 返回 false

10.5 代理对象的内部方法和内部插槽

代理对象是一个 特殊对象,其基本内部方法部分由 ECMAScript 代码实现。每个代理对象都有一个名为 [[ProxyHandler]] 的内部插槽。[[ProxyHandler]] 的值是一个对象,称为代理的 处理程序对象,或 null。处理程序对象的方法(见 表34)可以用来增强一个或多个代理对象的内部方法的实现。每个代理对象还有一个名为 [[ProxyTarget]] 的内部插槽,其值要么是一个对象,要么是 null 值。这个对象被称为代理的 目标对象

如果对象的基本内部方法(包括 [[Call]][[Construct]],如果适用)使用本节中的定义,则该对象是一个 代理特殊对象。这些内部方法在 ProxyCreate 中安装。

表34: 代理处理程序方法
内部方法 处理程序方法
[[GetPrototypeOf]] getPrototypeOf
[[SetPrototypeOf]] setPrototypeOf
[[IsExtensible]] isExtensible
[[PreventExtensions]] preventExtensions
[[GetOwnProperty]] getOwnPropertyDescriptor
[[DefineOwnProperty]] defineProperty
[[HasProperty]] has
[[Get]] get
[[Set]] set
[[Delete]] deleteProperty
[[OwnPropertyKeys]] ownKeys
[[Call]] apply
[[Construct]] construct

当调用处理程序方法来提供代理对象内部方法的实现时,处理程序方法会将代理的目标对象作为参数传递。代理的处理程序对象不一定具有与每个基本内部方法对应的方法。如果处理程序对象没有对应于内部陷阱的方法,则在代理上调用内部方法将导致调用代理目标对象上的相应内部方法。

代理对象的 [[ProxyHandler]][[ProxyTarget]] 内部插槽在对象创建时总是被初始化,并且通常不可修改。有些代理对象是以允许其随后被撤销的方式创建的。当代理被撤销时,其 [[ProxyHandler]][[ProxyTarget]] 内部插槽被设置为 null,导致在该代理对象上随后调用内部方法会抛出 TypeError 异常。

由于代理对象允许内部方法的实现由任意 ECMAScript 代码提供,因此可能会定义一个其处理程序方法违反 6.1.7.3 中定义的不变量的代理对象。一些在 6.1.7.3 中定义的内部方法不变量是基本的完整性不变量。这些不变量由本节中指定的代理对象内部方法明确执行。ECMAScript 实现必须在所有可能的不变量违反的情况下都具有健壮性。

在以下算法描述中,假设 O 是一个 ECMAScript 代理对象,P 是一个 属性键 值,V 是任何 ECMAScript 语言值,并且 Desc 是一个 属性描述符 记录。

10.5.1 [[GetPrototypeOf]] ( )

[[GetPrototypeOf]] 内部方法的 Proxy 异质对象 O 不接受任何参数,并返回 正常完成记录 ,其包含一个对象或 null,或者返回一个 抛出完成 。调用时执行以下步骤:

  1. 执行 ?  ValidateNonRevokedProxy (O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言handler 是一个 对象
  5. trap 为 ?  GetMethod (handler, "getPrototypeOf")。
  6. 如果 trapundefined,则:
    1. 返回 ? target.[[GetPrototypeOf]]()。
  7. handlerProto 为 ?  Call (trap, handler, « target »)。
  8. 如果 handlerProto 不是一个 对象 并且 handlerProto 不是 null,则抛出 TypeError 异常。
  9. extensibleTarget 为 ?  IsExtensible (target)。
  10. 如果 extensibleTargettrue,则返回 handlerProto
  11. targetProto 为 ? target.[[GetPrototypeOf]]()。
  12. 如果 SameValue (handlerProto, targetProto) 是 false,则抛出 TypeError 异常。
  13. 返回 handlerProto

Proxy 对象的 [[GetPrototypeOf]] 强制执行以下不变量:

  • [[GetPrototypeOf]] 的结果必须是一个对象或 null
  • 如果目标对象不可扩展,则应用于代理对象的 [[GetPrototypeOf]] 必须返回与应用于代理对象的目标对象的 [[GetPrototypeOf]] 相同的值。

10.5.2 [[SetPrototypeOf]] ( V )

[[SetPrototypeOf]] 内部方法的 Proxy 异质对象 O 接受参数 V(一个对象或 null),并返回一个 正常完成记录 ,其包含一个布尔值或返回一个 抛出完成 。调用时执行以下步骤:

  1. 执行 ?  ValidateNonRevokedProxy (O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言handler 是一个 对象
  5. trap 为 ?  GetMethod (handler, "setPrototypeOf")。
  6. 如果 trapundefined,则:
    1. 返回 ? target.[[SetPrototypeOf]](V)。
  7. booleanTrapResult ToBoolean (? Call (trap, handler, « target, V »))。
  8. 如果 booleanTrapResultfalse,则返回 false
  9. extensibleTarget 为 ?  IsExtensible (target)。
  10. 如果 extensibleTargettrue,则返回 true
  11. targetProto 为 ? target.[[GetPrototypeOf]]()。
  12. 如果 SameValue (V, targetProto) 是 false,则抛出 TypeError 异常。
  13. 返回 true

Proxy 对象的 [[SetPrototypeOf]] 强制执行以下不变量:

  • [[SetPrototypeOf]] 的结果是一个布尔值。
  • 如果目标对象不可扩展,则参数值必须与应用于目标对象的 [[GetPrototypeOf]] 的结果相同。

10.5.3 [[IsExtensible]] ( )

[[IsExtensible]] 内部方法的 Proxy 异质对象 O 不接受参数并返回一个 正常完成记录 ,其包含一个布尔值或返回一个 抛出完成 。调用时执行以下步骤:

  1. 执行 ?  ValidateNonRevokedProxy (O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言 handler 是一个 对象
  5. trap 为 ?  GetMethod (handler, "isExtensible")。
  6. 如果 trapundefined,则:
    1. 返回 ?  IsExtensible (target)。
  7. booleanTrapResult ToBoolean (? Call (trap, handler, « target »))。
  8. targetResult 为 ?  IsExtensible (target)。
  9. 如果 booleanTrapResult 不等于 targetResult,则抛出 TypeError 异常。
  10. 返回 booleanTrapResult

Proxy 对象的 [[IsExtensible]] 强制执行以下不变量:

  • [[IsExtensible]] 的结果是一个布尔值。
  • 应用于 Proxy 对象的 [[IsExtensible]] 必须返回与应用于 Proxy 对象的目标对象相同的参数值相同的结果。

10.5.4 [[PreventExtensions]] ( )

[[PreventExtensions]] 内部方法的 Proxy 异质对象 O 不接受参数并返回一个 正常完成记录 ,其包含一个布尔值或返回一个 抛出完成 。调用时执行以下步骤:

  1. 执行 ?  ValidateNonRevokedProxy (O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言 handler 是一个 对象
  5. trap 为 ?  GetMethod (handler, "preventExtensions")。
  6. 如果 trapundefined,则:
    1. 返回 ? target.[[PreventExtensions]]()
  7. booleanTrapResult ToBoolean (? Call (trap, handler, « target »))。
  8. 如果 booleanTrapResulttrue,则:
    1. extensibleTarget 为 ?  IsExtensible (target)。
    2. 如果 extensibleTargettrue,抛出 TypeError 异常。
  9. 返回 booleanTrapResult

Proxy 对象的 [[PreventExtensions]] 强制执行以下不变量:

  • [[PreventExtensions]] 的结果是一个布尔值。
  • 应用于 Proxy 对象的 [[PreventExtensions]] 仅当应用于 Proxy 对象的目标对象的 [[IsExtensible]] 结果为 false 时,才会返回 true

10.5.5 [[GetOwnProperty]] ( P )

[[GetOwnProperty]] 内部方法的 Proxy 异质对象 O 接受参数 P(一个 属性键 )并返回一个 正常完成记录 ,其包含一个 属性描述符 undefined,或者返回一个 抛出完成 。调用时执行以下步骤:

  1. 执行 ?  ValidateNonRevokedProxy (O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言 handler 是一个 对象
  5. trap 为 ?  GetMethod (handler, "getOwnPropertyDescriptor")。
  6. 如果 trapundefined,则:
    1. 返回 ? target.[[GetOwnProperty]](P)
  7. trapResultObj 为 ?  Call (trap, handler, «target, P »)。
  8. 如果 trapResultObj 不是一个 对象 trapResultObj 不是 undefined,抛出一个 TypeError 异常。
  9. targetDesc 为 ? target.[[GetOwnProperty]](P)
  10. 如果 trapResultObjundefined,则:
    1. 如果 targetDescundefined,返回 undefined
    2. 如果 targetDesc.[[Configurable]]false,抛出一个 TypeError 异常。
    3. extensibleTarget 为 ?  IsExtensible (target)。
    4. 如果 extensibleTargetfalse,抛出一个 TypeError 异常。
    5. 返回 undefined
  11. extensibleTarget 为 ?  IsExtensible (target)。
  12. resultDesc 为 ?  ToPropertyDescriptor (trapResultObj)。
  13. 执行 CompletePropertyDescriptor (resultDesc)。
  14. valid IsCompatiblePropertyDescriptor (extensibleTarget, resultDesc, targetDesc)。
  15. 如果 validfalse,抛出一个 TypeError 异常。
  16. 如果 resultDesc.[[Configurable]]false,则:
    1. 如果 targetDescundefinedtargetDesc.[[Configurable]]true,则:
      1. 抛出一个 TypeError 异常。
    2. 如果 resultDesc 有一个 [[Writable]] 字段并且 resultDesc.[[Writable]]false,则:
      1. 断言 targetDesc 有一个 [[Writable]] 字段。
      2. 如果 targetDesc.[[Writable]]true,抛出一个 TypeError 异常。
  17. 返回 resultDesc

Proxy 对象的 [[GetOwnProperty]] 强制执行以下不变量:

  • [[GetOwnProperty]] 的结果必须是一个对象或 undefined
  • 如果目标对象作为自身不可配置的属性存在,则该属性不能被报告为不存在。
  • 如果目标对象作为自身不可扩展的属性存在,则该属性不能被报告为不存在。
  • 如果目标对象是不可扩展的,且该属性不存在于目标对象的自身属性中,则该属性不能被报告为存在。
  • 除非目标对象的自身不可配置属性存在,否则该属性不能被报告为不可配置。
  • 除非目标对象的自身不可配置且不可写的属性存在,否则该属性不能被报告为既不可配置又不可写。

10.5.6 [[DefineOwnProperty]] ( P, Desc )

[[DefineOwnProperty]] 内部方法的 Proxy 异质对象 O 接受参数 P(一个 属性键 )和 Desc(一个 属性描述符 )并返回一个 正常完成记录 ,其包含一个布尔值或返回一个 抛出完成 。调用时执行以下步骤:

  1. 执行 ?  ValidateNonRevokedProxy (O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言 handler 是一个 对象
  5. trap 为 ?  GetMethod (handler, "defineProperty")。
  6. 如果 trapundefined,则:
    1. 返回 ? target.[[DefineOwnProperty]](P, Desc)
  7. descObj 为 ?  FromPropertyDescriptor (Desc)。
  8. booleanTrapResult ToBoolean (? Call (trap, handler, «target, P, descObj »))。
  9. 如果 booleanTrapResultfalse,返回 false
  10. targetDesc 为 ? target.[[GetOwnProperty]](P)
  11. extensibleTarget 为 ?  IsExtensible (target)。
  12. 如果 Desc 有一个 [[Configurable]] 字段且 Desc.[[Configurable]]false,则:
    1. settingConfigFalsetrue
  13. 否则,
    1. settingConfigFalsefalse
  14. 如果 targetDescundefined,则:
    1. 如果 extensibleTargetfalse,抛出一个 TypeError 异常。
    2. 如果 settingConfigFalsetrue,抛出一个 TypeError 异常。
  15. 否则,
    1. 如果 IsCompatiblePropertyDescriptor (extensibleTarget, Desc, targetDesc) 是 false,抛出一个 TypeError 异常。
    2. 如果 settingConfigFalsetruetargetDesc.[[Configurable]]true,抛出一个 TypeError 异常。
    3. 如果 IsDataDescriptor (targetDesc) 是 truetargetDesc.[[Configurable]]false,且 targetDesc.[[Writable]]true,则:
      1. 如果 Desc 有一个 [[Writable]] 字段且 Desc.[[Writable]]false,抛出一个 TypeError 异常。
  16. 返回 true

Proxy 对象的 [[DefineOwnProperty]] 强制执行以下不变量:

  • [[DefineOwnProperty]] 的结果是一个布尔值。
  • 如果目标对象是不可扩展的,则不能添加属性。
  • 除非目标对象存在相应的不可配置自身属性,否则属性不能是不可配置的。
  • 除非目标对象存在相应的不可配置且不可写的自身属性,否则不可配置的属性不能是不可写的。
  • 如果属性有相应的目标对象属性,则使用属性的属性描述符应用于目标对象的 [[DefineOwnProperty]] 不会抛出异常。

10.5.7 [[HasProperty]] ( P )

[[HasProperty]] 内部方法的 Proxy 异质对象 O 接受参数 P(一个 属性键 )并返回一个 正常完成记录 ,其包含一个布尔值或返回一个 抛出完成 。调用时执行以下步骤:

  1. 执行 ?  ValidateNonRevokedProxy (O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言 handler 是一个 对象
  5. trap 为 ?  GetMethod (handler, "has")。
  6. 如果 trapundefined,则:
    1. 返回 ? target.[[HasProperty]](P)
  7. booleanTrapResult ToBoolean (? Call (trap, handler, «target, P »))。
  8. 如果 booleanTrapResultfalse,则:
    1. targetDesc 为 ? target.[[GetOwnProperty]](P)
    2. 如果 targetDesc 不是 undefined,则:
      1. 如果 targetDesc.[[Configurable]]false,抛出一个 TypeError 异常。
      2. extensibleTarget 为 ?  IsExtensible (target)。
      3. 如果 extensibleTargetfalse,抛出一个 TypeError 异常。
  9. 返回 booleanTrapResult

Proxy 对象的 [[HasProperty]] 强制执行以下不变量:

  • [[HasProperty]] 的结果是一个布尔值。
  • 如果属性作为目标对象的不可配置自身属性存在,则不能报告该属性不存在。
  • 如果属性作为目标对象的自身属性存在且目标对象不可扩展,则不能报告该属性不存在。

10.5.8 [[Get]] ( P, Receiver )

[[Get]] 内部方法的 Proxy 异质对象 O 接受参数 P(一个 属性键 )和 Receiver(一个 ECMAScript 语言值 ),并返回一个 正常完成记录 ,其包含一个 ECMAScript 语言值 或返回一个 抛出完成 。调用时执行以下步骤:

  1. 执行 ?  ValidateNonRevokedProxy (O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言 handler 是一个 对象
  5. trap 为 ?  GetMethod (handler, "get")。
  6. 如果 trapundefined,则:
    1. 返回 ? target.[[Get]](P, Receiver)
  7. trapResult 为 ?  Call (trap, handler, «target, P, Receiver ») 。
  8. targetDesc 为 ? target.[[GetOwnProperty]](P)
  9. 如果 targetDesc 不是 undefinedtargetDesc.[[Configurable]]false,则:
    1. 如果 IsDataDescriptor (targetDesc) 是 truetargetDesc.[[Writable]]false,则:
      1. 如果 SameValue (trapResult, targetDesc.[[Value]]) 是 false,抛出一个 TypeError 异常。
    2. 如果 IsAccessorDescriptor (targetDesc) 是 true 且 targetDesc.[[Get]]undefined,则:
      1. 如果 trapResult 不是 undefined,抛出一个 TypeError 异常。
  10. 返回 trapResult

Proxy 对象的 [[Get]] 强制执行以下不变量:

  • 如果目标对象属性是一个不可写、不可配置的自身 数据属性 ,则报告的属性值必须与相应的目标对象属性的值相同。
  • 如果相应的目标对象属性是一个不可配置的自身 访问器属性 且其 [[Get]] 属性为 undefined,则报告的属性值必须为 undefined

10.5.9 [[Set]] ( P, V, Receiver )

[[Set]] 内部方法的 Proxy 异质对象 O 接受参数 P(一个 属性键 ),V(一个 ECMAScript 语言值 )和 Receiver(一个 ECMAScript 语言值 ),并返回一个 正常完成记录 ,其包含一个布尔值或返回一个 抛出完成 。调用时执行以下步骤:

  1. 执行 ?  ValidateNonRevokedProxy (O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言 handler 是一个 对象
  5. trap 为 ?  GetMethod (handler, "set")。
  6. 如果 trapundefined,则:
    1. 返回 ? target.[[Set]](P, V, Receiver)
  7. booleanTrapResult ToBoolean (? Call (trap, handler, «target, P, V, Receiver »))。
  8. 如果 booleanTrapResultfalse,返回 false
  9. targetDesc 为 ? target.[[GetOwnProperty]](P)
  10. 如果 targetDesc 不是 undefinedtargetDesc.[[Configurable]]false,则:
    1. 如果 IsDataDescriptor (targetDesc) 是 true 且 targetDesc.[[Writable]]false,则:
      1. 如果 SameValue (V, targetDesc.[[Value]]) 是 false,抛出一个 TypeError 异常。
    2. 如果 IsAccessorDescriptor (targetDesc) 是 true,则:
      1. 如果 targetDesc.[[Set]]undefined,抛出一个 TypeError 异常。
  11. 返回 true

Proxy 对象的 [[Set]] 强制执行以下不变量:

  • [[Set]] 的结果是一个布尔值。
  • 如果相应的目标对象属性是一个不可写、不可配置的自身 数据属性 ,则不能将属性值更改为与相应的目标对象属性的值不同的值。
  • 如果相应的目标对象属性是一个不可配置的自身 访问器属性 且其 [[Set]] 属性为 undefined,则不能设置该属性的值。

10.5.10 [[Delete]] ( P )

[[Delete]] 内部方法的 Proxy 异质对象 O 接受参数 P(一个 属性键 ),并返回一个 正常完成记录 ,其包含一个布尔值或返回一个 抛出完成 。调用时执行以下步骤:

  1. 执行 ?  ValidateNonRevokedProxy (O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言 handler 是一个 对象
  5. trap 为 ?  GetMethod (handler, "deleteProperty")。
  6. 如果 trapundefined,则:
    1. 返回 ? target.[[Delete]](P)
  7. booleanTrapResult ToBoolean (? Call (trap, handler, «target, P »))。
  8. 如果 booleanTrapResultfalse,返回 false
  9. targetDesc 为 ? target.[[GetOwnProperty]](P)
  10. 如果 targetDescundefined,返回 true
  11. 如果 targetDesc.[[Configurable]]false,抛出一个 TypeError 异常。
  12. extensibleTarget 为 ?  IsExtensible (target)。
  13. 如果 extensibleTargetfalse,抛出一个 TypeError 异常。
  14. 返回 true

Proxy 对象的 [[Delete]] 强制执行以下不变量:

  • [[Delete]] 的结果是一个布尔值。
  • 如果目标对象存在一个不可配置的自身属性,则不能将其报告为已删除。
  • 如果目标对象存在一个自身属性且目标对象是不可扩展的,则不能将其报告为已删除。

10.5.11 [[OwnPropertyKeys]] ( )

[[OwnPropertyKeys]] 内部方法的 Proxy 异质对象 O 不接受任何参数,并返回一个 正常完成记录 ,其包含一个 列表 属性键 或返回一个 抛出完成 。调用时执行以下步骤:

  1. 执行 ?  ValidateNonRevokedProxy (O)。
  2. targetO.[[ProxyTarget]]
  3. handlerO.[[ProxyHandler]]
  4. 断言 handler 是一个 对象
  5. trap 为 ?  GetMethod (handler, "ownKeys")。
  6. 如果 trapundefined,则:
    1. 返回 ? target.[[OwnPropertyKeys]]()
  7. trapResultArray 为 ?  Call (trap, handler, «target »)。
  8. trapResult 为 ?  CreateListFromArrayLike (trapResultArray, «String, Symbol »)。
  9. 如果 trapResult 包含任何重复项,抛出一个 TypeError 异常。
  10. extensibleTarget 为 ?  IsExtensible (target)。
  11. targetKeys 为 ? target.[[OwnPropertyKeys]]()
  12. 断言 targetKeys 是一个包含 列表 属性键
  13. 断言 targetKeys 不包含重复项。
  14. targetConfigurableKeys 为一个新的空 列表
  15. targetNonconfigurableKeys 为一个新的空 列表
  16. 对于 targetKeys 的每个元素 key,执行以下步骤:
    1. desc 为 ? target.[[GetOwnProperty]](key)
    2. 如果 desc 不是 undefineddesc.[[Configurable]]false,则:
      1. key 追加到 targetNonconfigurableKeys
    3. 否则:
      1. key 追加到 targetConfigurableKeys
  17. 如果 extensibleTargettruetargetNonconfigurableKeys 为空,则:
    1. 返回 trapResult
  18. uncheckedResultKeys 为一个包含 trapResult 元素的 列表
  19. 对于 targetNonconfigurableKeys 的每个元素 key,执行以下步骤:
    1. 如果 uncheckedResultKeys 不包含 key,抛出一个 TypeError 异常。
    2. uncheckedResultKeys 中移除 key
  20. 如果 extensibleTargettrue,返回 trapResult
  21. 对于 targetConfigurableKeys 的每个元素 key,执行以下步骤:
    1. 如果 uncheckedResultKeys 不包含 key,抛出一个 TypeError 异常。
    2. uncheckedResultKeys 中移除 key
  22. 如果 uncheckedResultKeys 不为空,抛出一个 TypeError 异常。
  23. 返回 trapResult

Proxy 对象的 [[OwnPropertyKeys]] 强制执行以下不变量:

  • [[OwnPropertyKeys]] 的结果是一个 列表
  • 返回的 列表 不包含重复项。
  • 每个结果 列表 元素的类型是字符串或符号。
  • 结果 列表 必须包含目标对象所有不可配置自身属性的键。
  • 如果目标对象是不可扩展的,则结果 列表 必须包含目标对象自身属性的所有键且不包含其他值。

10.5.12 [[Call]] ( thisArgument, argumentsList )

[[Call]] 内部方法用于 Proxy 奇异对象 O。它接受参数 thisArgument(一个 ECMAScript 语言值)和 argumentsList(一个 列表,包含 ECMAScript 语言值),并返回一个包含 正常完成记录,其中包含一个 ECMAScript 语言值 或者一个 抛出完成记录。它在被调用时执行以下步骤:

  1. 执行 ? ValidateNonRevokedProxy(O).
  2. target 等于 O.[[ProxyTarget]].
  3. handler 等于 O.[[ProxyHandler]].
  4. 断言: handler 是一个对象。
  5. trap 等于 ? GetMethod(handler, "apply").
  6. 如果 trap 是 undefined,则
    1. 返回 ? Call(target, thisArgument, argumentsList).
  7. argArray 等于 CreateArrayFromList(argumentsList).
  8. 返回 ? Call(trap, handler, « target, thisArgument, argArray »).

Proxy 奇异对象 只有在其 [[ProxyTarget]] 内部槽的初始值是一个具有 [[Call]] 内部方法的对象时,才具有 [[Call]] 内部方法。

10.5.13 [[Construct]] ( argumentsList, newTarget )

[[Construct]] 内部方法用于 Proxy 奇异对象 O。它接受参数 argumentsList(一个 列表,包含 ECMAScript 语言值)和 newTarget(一个 构造函数),并返回一个包含对象的 正常完成记录 或一个 抛出完成记录。它在被调用时执行以下步骤:

  1. 执行 ? ValidateNonRevokedProxy(O).
  2. target 等于 O.[[ProxyTarget]].
  3. 断言: IsConstructor(target) 为 true。
  4. handler 等于 O.[[ProxyHandler]].
  5. 断言: handler 是一个对象。
  6. trap 等于 ? GetMethod(handler, "construct").
  7. 如果 trap 是 undefined,则
    1. 返回 ? Construct(target, argumentsList, newTarget).
  8. argArray 等于 CreateArrayFromList(argumentsList).
  9. newObj 等于 ? Call(trap, handler, « target, argArray, newTarget »).
  10. 如果 newObj 不是一个对象,抛出一个 TypeError 异常。
  11. 返回 newObj.
注 1

Proxy 奇异对象 只有在其 [[ProxyTarget]] 内部槽的初始值是一个具有 [[Construct]] 内部方法的对象时,才具有 [[Construct]] 内部方法。

注 2

[[Construct]] 对于 Proxy 对象强制执行以下不变量:

  • [[Construct]] 的结果必须是一个对象。

10.5.14 ValidateNonRevokedProxy ( proxy )

抽象操作 ValidateNonRevokedProxy 接受参数 proxy(一个 Proxy 奇异对象),并返回包含 正常完成记录unused 或者一个 抛出完成记录。如果 proxy 已被撤销,则抛出 TypeError 异常。它在被调用时执行以下步骤:

  1. 如果 proxy.[[ProxyTarget]]null,抛出 TypeError 异常。
  2. 断言: proxy.[[ProxyHandler]] 不是 null
  3. 返回 unused

10.5.15 ProxyCreate ( target, handler )

抽象操作 ProxyCreate 接受参数 target(一个 ECMAScript 语言值)和 handler(一个 ECMAScript 语言值),并返回包含 正常完成记录Proxy 奇异对象 或一个 抛出完成记录。它用于指定新 Proxy 对象的创建。它在被调用时执行以下步骤:

  1. 如果 target 不是一个对象,抛出 TypeError 异常。
  2. 如果 handler 不是一个对象,抛出 TypeError 异常。
  3. P 等于 MakeBasicObject[[ProxyHandler]], [[ProxyTarget]] »)。
  4. 设置 P 的基本内部方法,除了 [[Call]][[Construct]],按照 10.5 中的定义。
  5. 如果 IsCallable(target) 为 true,则
    1. 设置 P.[[Call]],如 10.5.12 中所述。
    2. 如果 IsConstructor(target) 为 true,则
      1. 设置 P.[[Construct]],如 10.5.13 中所述。
  6. 设置 P.[[ProxyTarget]]target
  7. 设置 P.[[ProxyHandler]]handler
  8. 返回 P

11 ECMAScript 语言:源代码

11.1 源代码

语法

SourceCharacter :: 任何 Unicode 代码点

ECMAScript 源代码 是一系列 Unicode 代码点。在 ECMAScript 语法允许的地方,所有从 U+0000 到 U+10FFFF 的 Unicode 代码点值,包括代理代码点,都可以出现在 ECMAScript 源代码中。用于存储和交换 ECMAScript 源代码的实际编码与本规范无关。不论外部源代码编码如何,符合规范的 ECMAScript 实现都将源代码处理为等效的 SourceCharacter 值序列,每个 SourceCharacter 都是一个 Unicode 代码点。符合规范的 ECMAScript 实现不要求对源代码进行任何规范化,或表现得像在执行源代码的规范化。

组合字符序列的组成部分被视为单独的 Unicode 代码点,即使用户可能将整个序列视为一个字符。

注意

在字符串字面量、正则表达式字面量、模板字面量和标识符中,任何 Unicode 代码点也可以使用 Unicode 转义序列来表示,显式表达代码点的数值。在注释中,这样的转义序列实际上被忽略,作为注释的一部分。

ECMAScript 与 Java 编程语言在 Unicode 转义序列的行为上有所不同。例如,在 Java 程序中,如果 Unicode 转义序列 \u000A 出现在单行注释中,它会被解释为行终止符(Unicode 代码点 U+000A 是换行符(LF)),因此下一个代码点不再是注释的一部分。同样,如果 Unicode 转义序列 \u000A 出现在 Java 程序的字符串字面量中,它也会被解释为行终止符,字符串字面量中不允许有行终止符——必须写成 \n 而不是 \u000A,以使换行符(LF)成为字符串字面量的字符串值的一部分。在 ECMAScript 程序中,出现在注释中的 Unicode 转义序列从不被解释,因此不能终止注释。同样,出现在 ECMAScript 程序的字符串字面量中的 Unicode 转义序列始终是字面量的一部分,永远不会被解释为行终止符或可能终止字符串字面量的代码点。

11.1.1 静态语义: UTF16EncodeCodePoint ( cp )

抽象操作 UTF16EncodeCodePoint 接受参数 cp(一个 Unicode 代码点)并返回一个字符串。调用时,它执行以下步骤:

  1. 断言: 0 ≤ cp ≤ 0x10FFFF。
  2. 如果 cp ≤ 0xFFFF,返回由数值为 cp 的代码单元组成的字符串值。
  3. cu1 为数值为 向下取整((cp - 0x10000) / 0x400) + 0xD800 的代码单元。
  4. cu2 为数值为 ((cp - 0x10000) 0x400) + 0xDC00 的代码单元。
  5. 返回 字符串连接 cu1cu2 的结果。

11.1.2 静态语义: CodePointsToString ( text )

抽象操作 CodePointsToString 接受参数 text(一个 Unicode 代码点序列)并返回一个字符串。它将 text 转换为字符串值,如 6.1.4 中所述。调用时,它执行以下步骤:

  1. result 为空字符串。
  2. 对于 text 中的每个代码点 cp,执行以下步骤
    1. result 设为 字符串连接 resultUTF16EncodeCodePoint(cp) 的结果。
  3. 返回 result

11.1.3 静态语义: UTF16SurrogatePairToCodePoint ( lead, trail )

抽象操作 UTF16SurrogatePairToCodePoint 接受参数 lead(一个代码单元)和 trail(一个代码单元),并返回一个代码点。形成 UTF-16 代理对 的两个代码单元将转换为一个代码点。调用时,它执行以下步骤:

  1. 断言: lead 是一个 前导代理项 并且 trail 是一个 尾随代理项
  2. cp 为 (lead - 0xD800) × 0x400 + (trail - 0xDC00) + 0x10000。
  3. 返回代码点 cp

11.1.4 静态语义: CodePointAt ( string, position )

抽象操作 CodePointAt 接受参数 string(一个字符串)和 position(一个非负 整数),并返回一个包含字段 [[CodePoint]](一个代码点)、[[CodeUnitCount]](一个正的 整数)、[[IsUnpairedSurrogate]](一个布尔值)的 记录。它将 string 解释为 UTF-16 编码的代码点序列,如 6.1.4 中所述,并从索引 position 处的代码单元开始读取单个代码点。调用时,它执行以下步骤:

  1. sizestring 的长度。
  2. 断言: position ≥ 0 并且 position < size
  3. firststring 内索引 position 处的代码单元。
  4. cp 为数值为 first 的代码点。
  5. 如果 first 既不是 前导代理项 也不是 尾随代理项,则
    1. 返回 记录 { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: false }。
  6. 如果 first尾随代理项 或者 position + 1 = size,则
    1. 返回 记录 { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }。
  7. secondstring 内索引 position + 1 处的代码单元。
  8. 如果 second 不是 尾随代理项,则
    1. 返回 记录 { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }。
  9. cp 设置为 UTF16SurrogatePairToCodePoint(first, second)。
  10. 返回 记录 { [[CodePoint]]: cp, [[CodeUnitCount]]: 2, [[IsUnpairedSurrogate]]: false }。

11.1.5 静态语义: StringToCodePoints ( string )

抽象操作 StringToCodePoints 接受参数 string(一个字符串)并返回一个代码点的 列表。它返回将 string 解释为 UTF-16 编码的 Unicode 文本后得到的 Unicode 代码点序列,如 6.1.4 中所述。调用时,它执行以下步骤:

  1. codePoints 为一个新的空的 列表
  2. sizestring 的长度。
  3. position 为 0。
  4. 重复,当 position 小于 size 时,
    1. cpCodePointAt(string, position)。
    2. cp.[[CodePoint]] 添加到 codePoints
    3. position 设置为 position + cp.[[CodeUnitCount]]
  5. 返回 codePoints

11.1.6 静态语义: ParseText ( sourceText, goalSymbol )

抽象操作 ParseText 接受参数 sourceText(一个 Unicode 代码点序列)和 goalSymbol(ECMAScript 语法中的一个非终结符)并返回一个 解析节点或一个非空的 列表,其中包含 SyntaxError 对象。调用时,它执行以下步骤:

  1. 尝试使用 goalSymbol 作为目标符号解析 sourceText,并分析解析结果是否有 早期错误条件。解析和 早期错误检测可以以 实现定义 的方式交错进行。
  2. 如果解析成功且没有发现早期错误,则返回解析节点goalSymbol 的一个实例),该节点位于解析树的根节点。
  3. 否则,返回一个包含一个或多个 SyntaxError 对象的列表,这些对象表示解析错误和/或 早期错误。如果存在多个解析错误或 早期错误,则列表中的错误对象数量和排序是实现定义的,但至少必须存在一个。
注释 1

考虑一个在特定点有早期错误的文本,并且在后续点有语法错误。一个先进行解析然后进行早期错误检测的实现可能会报告语法错误并且不进行早期错误检测。一个将两者交错进行的实现可能会报告早期错误并且不继续发现语法错误。第三个实现可能会报告两个错误。这些行为都是符合规范的。

注释 2

另见第 17 节。

11.2 Types of Source Code

有四种类型的 ECMAScript 代码:

Note 1

Function code 通常以函数定义的主体形式提供(15.2),箭头函数定义(15.3),方法定义(15.4),生成器函数定义(15.5),异步函数定义(15.8),异步生成器函数定义(15.6),和异步箭头函数(15.9)。Function code 也来源于 Function 构造函数(constructor)(20.2.1.1),GeneratorFunction 构造函数(constructor)(27.3.1.1),以及 AsyncFunction 构造函数(constructor)(27.7.1.1)的参数。

Note 2

BindingIdentifier 包含在函数代码中的实际效果是,即使周围代码不是 严格模式代码,包含 "use strict" 指令的函数体名称为 BindingIdentifier 的函数仍然会应用 严格模式代码 的早期错误。

11.2.1 指令序言和 "use strict" 指令

指令序言 是出现在 StatementListItemModuleItem 的初始位置处的最长序列 ExpressionStatement。这些 ExpressionStatement 以一个 StringLiteral 标记及后续的分号组成。这个分号可以是显式的,也可以由自动分号插入 (12.10)。 指令序言 可以是一个空序列。

"use strict" 指令 是出现在 指令序言 中的 ExpressionStatement,其 StringLiteral 为精确的代码点序列 "use strict"'use strict'"use strict" 指令 不应包含 EscapeSequenceLineContinuation

指令序言 可以包含多个 "use strict" 指令。 但是,如果出现这种情况,实施可能会发出警告。

注意

ExpressionStatement 在包含生成中的正常评估中被评估。实现可以为出现在 指令序言 中 但不是 "use strict" 指令ExpressionStatement 定义特定的含义。 如果存在适当的通知机制,则在 指令序言 中 碰到不是 "use strict" 指令 并且 没有实现定义含义的 ExpressionStatement 时,实现应发出警告。

11.2.2 严格模式代码

ECMAScript 语法单元可以使用无限制或严格模式语法和语义进行处理 (4.3.2)。在以下情况下,代码被解释为 严格模式代码

不是严格模式代码的 ECMAScript 代码称为 非严格代码

11.2.3 非 ECMAScript 函数

ECMAScript 实现可能支持对函数 异质对象 的求值,其求值行为以某种 宿主定义 的可执行代码形式表达,而不是 ECMAScript 源文本。无论 函数对象 是在 ECMAScript 代码中定义的,还是内置函数,从调用或被调用的 ECMAScript 代码的角度来看,都是不可观察的。

12 ECMAScript 语言:词法语法

ECMAScript 脚本模块的源文本首先被转换为一系列输入元素,这些输入元素包括标记、行终止符、注释或空白。源文本从左到右扫描,反复采用最长可能的代码点序列作为下一个输入元素。

在多个情况下,词法输入元素的识别对消耗输入元素的语法语境是敏感的。这需要词法语法的多个目标符号InputElementHashbangOrRegExp目标在脚本模块的开头使用。InputElementRegExpOrTemplateTail目标在语法语境中使用,其中允许正则表达式文本模板中间模板尾部InputElementRegExp目标符号在所有允许正则表达式文本但不允许模板中间模板尾部的语法语境中使用。InputElementTemplateTail目标在所有允许模板中间模板尾部但不允许正则表达式文本的语法语境中使用。在所有其他语境中,InputElementDiv用作词法目标符号

Note

使用多个词法目标确保没有词法歧义会影响自动分号插入。例如,没有语法语境同时允许前导除法或除法赋值和前导正则表达式文本。这不受分号插入的影响(见12.10);例如以下情况:

a = b
/hi/g.exec(c).map(d);

在一个行终止符之后的第一个非空白、非注释代码点是U+002F(SOLIDUS),且语法上下文允许除法或除法赋值,不会在行终止符处插入分号。也就是说,上述示例的解释方式与以下相同:

a = b / hi / g.exec(c).map(d);

语法

InputElementDiv :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator RightBracePunctuator InputElementRegExp :: WhiteSpace LineTerminator Comment CommonToken RightBracePunctuator RegularExpressionLiteral InputElementRegExpOrTemplateTail :: WhiteSpace LineTerminator Comment CommonToken RegularExpressionLiteral TemplateSubstitutionTail InputElementTemplateTail :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator TemplateSubstitutionTail InputElementHashbangOrRegExp :: WhiteSpace LineTerminator Comment CommonToken HashbangComment RegularExpressionLiteral

12.1 Unicode 格式控制字符

Unicode 格式控制字符(即 Unicode 字符数据库中类别为 “Cf” 的字符,如左到右标记或右到左标记)是用于在缺乏高级协议(如标记语言)的情况下控制一段文本格式的控制代码。

允许在源文本中使用格式控制字符以便于编辑和显示是很有用的。所有格式控制字符都可以在注释、字符串字面量、模板字面量和正则表达式字面量中使用。

U+200C(零宽非连接符)和 U+200D(零宽连接符)是用于在某些语言中形成单词或短语时进行必要区分的格式控制字符。在 ECMAScript 源文本 中,这些代码点也可以在第一个字符之后用于 IdentifierName 中。

U+FEFF(零宽不换行空格)是主要用于文本开头的格式控制字符,用来标记它为 Unicode 并允许检测文本的编码和字节顺序。出于这种目的而使用的 <ZWNBSP> 字符有时也会出现在文本的开头之后,例如由于文件连接的结果。在 ECMAScript 源文本 中,<ZWNBSP> 代码点被视为空白字符(见 12.2)。

某些格式控制字符在注释、字符串字面量和正则表达式字面量之外的特殊处理在 表 35 中总结。

表 35: 格式控制代码点的使用
代码点 名称 缩写 用法
U+200C 零宽非连接符 <ZWNJ> IdentifierPart
U+200D 零宽连接符 <ZWJ> IdentifierPart
U+FEFF 零宽不换行空格 <ZWNBSP> WhiteSpace

12.2 空白符

空白符代码点用于提高源文本的可读性,并将词法单元(不可分割的词法单位)彼此分开,但除此之外没有其他意义。空白符代码点可以出现在任意两个词法单元之间,以及输入的开头或结尾。空白符代码点可以出现在 StringLiteralRegularExpressionLiteralTemplateTemplateSubstitutionTail 中,在这些情况下,它们被视为构成字面值一部分的有效代码点。它们也可以出现在 Comment 中,但不能出现在任何其他类型的词法单元中。

ECMAScript 的空白符代码点列在 表 36 中。

表 36: 空白符代码点
代码点 名称 缩写
U+0009 CHARACTER TABULATION <TAB>
U+000B LINE TABULATION <VT>
U+000C FORM FEED (FF) <FF>
U+FEFF ZERO WIDTH NO-BREAK SPACE <ZWNBSP>
general category 中的任意代码点 “Space_Separator” <USP>
注释 1

U+0020 (SPACE) 和 U+00A0 (NO-BREAK SPACE) 代码点是 <USP> 的一部分。

注释 2

除了表 表 36 中列出的代码点外,ECMAScript 的 WhiteSpace 有意排除了所有具有 Unicode “White_Space” 属性但未分类为 general category “Space_Separator” (“Zs”) 的代码点。

语法

WhiteSpace :: <TAB> <VT> <FF> <ZWNBSP> <USP>

12.3 行终止符

像空白符代码点一样,行终止符代码点用于提高源文本的可读性,并将词法单元(不可分割的词法单位)彼此分开。然而,与空白符代码点不同,行终止符对语法规则的行为有一定影响。通常,行终止符可以出现在任意两个词法单元之间,但在某些地方,语法规则禁止它们的出现。行终止符还会影响自动分号插入的过程(12.10)。行终止符不能出现在任何词法单元内部,除了 StringLiteralTemplateTemplateSubstitutionTail。<LF> 和 <CR> 行终止符不能出现在 StringLiteral 词法单元中,除非作为 LineContinuation 的一部分。

行终止符可以出现在 MultiLineComment 中,但不能出现在 SingleLineComment 中。

行终止符包含在正则表达式中的 \s 类匹配的空白符代码点集合中。

ECMAScript 行终止符代码点列在 表 37 中。

表 37: 行终止符代码点
代码点 Unicode 名称 缩写
U+000A LINE FEED (LF) <LF>
U+000D CARRIAGE RETURN (CR) <CR>
U+2028 LINE SEPARATOR <LS>
U+2029 PARAGRAPH SEPARATOR <PS>

只有表 表 37 中的 Unicode 代码点被视为行终止符。其他新的行或换行 Unicode 代码点不被视为行终止符,但如果它们符合 表 36 中列出的要求,则被视为空白符。序列 <CR><LF> 通常用作行终止符。出于报告行号的目的,应将其视为单个 SourceCharacter

语法

LineTerminator :: <LF> <CR> <LS> <PS> LineTerminatorSequence :: <LF> <CR> [lookahead ≠ <LF>] <LS> <PS> <CR> <LF>

12.4 注释

注释可以是单行或多行。多行注释不能嵌套。

由于单行注释可以包含任何 Unicode 代码点,除了 LineTerminator 代码点,并且由于通用规则是词法单元总是尽可能长,因此单行注释总是由 // 标记到行尾的所有代码点组成。然而,行尾的 LineTerminator 不被视为单行注释的一部分;它由词法语法单独识别,并成为语法解析的输入元素流的一部分。这一点非常重要,因为它意味着单行注释的存在或不存在不会影响自动分号插入的过程(见 12.10)。

注释表现得像空白符,并被丢弃,除了如果一个 MultiLineComment 包含一个行终止符代码点,那么整个注释将被视为 LineTerminator,以便语法解析。

语法

Comment :: MultiLineComment SingleLineComment MultiLineComment :: /* MultiLineCommentCharsopt */ MultiLineCommentChars :: MultiLineNotAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt PostAsteriskCommentChars :: MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt MultiLineNotAsteriskChar :: SourceCharacter 但不包括 * MultiLineNotForwardSlashOrAsteriskChar :: SourceCharacter 但不包括 /* SingleLineComment :: // SingleLineCommentCharsopt SingleLineCommentChars :: SingleLineCommentChar SingleLineCommentCharsopt SingleLineCommentChar :: SourceCharacter 但不包括 LineTerminator

本节中的一些规则在 B.1.1 中给出了替代定义。

12.5 Hashbang 注释

Hashbang 注释是位置敏感的,并且像其他类型的注释一样,从语法解析的输入元素流中被丢弃。

语法

HashbangComment :: #! SingleLineCommentCharsopt

12.6 词法单元(Tokens)

语法

CommonToken :: IdentifierName PrivateIdentifier Punctuator NumericLiteral StringLiteral Template Note

DivPunctuator, RegularExpressionLiteral, RightBracePunctuator, 和 TemplateSubstitutionTail 派生了其他不包含在 CommonToken 生产式中的词法单元。

12.7 名称和关键字

IdentifierNameReservedWord 是根据 Unicode Standard Annex #31, Identifier and Pattern Syntax 所给出的默认标识符语法解释的词法单元,并进行了一些小的修改。 ReservedWordIdentifierName 的一个枚举子集。语法定义了 Identifier 为不属于 ReservedWordIdentifierName 。Unicode 标识符语法基于 Unicode 标准所定义的字符属性。所有符合 ECMAScript 实现的标识符都必须按照最新版本的 Unicode 标准中的指定类别处理 Unicode 代码点。ECMAScript 实现可以识别在 Unicode 标准的后续版本中定义的标识符代码点。

注 1

本标准指定了特定的代码点添加:U+0024 (美元符号) 和 U+005F (下划线) 在 IdentifierName 的任何地方都允许使用,并且 U+200C (零宽度非连接符) 和 U+200D (零宽度连接符) 在 IdentifierName 的第一个代码点之后的任何地方都允许使用。

语法

PrivateIdentifier :: # IdentifierName IdentifierName :: IdentifierStart IdentifierName IdentifierPart IdentifierStart :: IdentifierStartChar \ UnicodeEscapeSequence IdentifierPart :: IdentifierPartChar \ UnicodeEscapeSequence IdentifierStartChar :: UnicodeIDStart $ _ IdentifierPartChar :: UnicodeIDContinue $ <ZWNJ> <ZWJ> AsciiLetter :: one of a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z UnicodeIDStart :: 任何具有 Unicode 属性 “ID_Start” 的 Unicode 代码点 UnicodeIDContinue :: 任何具有 Unicode 属性 “ID_Continue” 的 Unicode 代码点

UnicodeEscapeSequence 的非终结符定义见 12.9.4

注 2

非终结符 IdentifierPart 通过 UnicodeIDContinue 派生出 _

注 3

具有 Unicode 属性 “ID_Start” 和 “ID_Continue” 的代码点集合分别包括具有 Unicode 属性 “Other_ID_Start” 和 “Other_ID_Continue” 的代码点。

12.7.1 标识符名称

IdentifierName 中允许使用 Unicode 转义序列,其中它们贡献了一个等于 IdentifierCodePoint 的单个 Unicode 代码点 UnicodeEscapeSequence 。在转义序列前的 \ 不贡献任何代码点。Unicode 转义序列不能用于对 IdentifierName 贡献一个代码点,该代码点本来就是无效的。换句话说,如果将 \ Unicode 转义序列替换为它所贡献的 SourceCharacter ,结果仍然必须是一个有效的 IdentifierName ,并且与原始的 IdentifierName 拥有完全相同的 SourceCharacter 序列。在本规范中的所有标识符名称解释都是基于它们的实际代码点的,无论是否使用转义序列对任何特定的代码点进行贡献。

根据 Unicode 标准,两个规范等效的 IdentifierName 是不相等的,除非在替换每个 Unicode 转义序列后,它们由完全相同的代码点序列表示。

12.7.1.1 静态语义:早期错误

IdentifierStart :: \ UnicodeEscapeSequence IdentifierPart :: \ UnicodeEscapeSequence

12.7.1.2 静态语义:IdentifierCodePoints

语法导向操作 IdentifierCodePoints 不接受任何参数,并返回一个代码点列表。它在以下各生成式上分段定义:

IdentifierName :: IdentifierStart
  1. cpIdentifierCodePointIdentifierStart
  2. 返回 « cp »。
IdentifierName :: IdentifierName IdentifierPart
  1. cpsIdentifierCodePoints 派生出的 IdentifierName
  2. cpIdentifierCodePointIdentifierPart
  3. 返回 列表串联cps 和 « cp »。

12.7.1.3 静态语义:IdentifierCodePoint

语法导向操作 IdentifierCodePoint 不接受任何参数并返回一个代码点。它在以下各生成式上分段定义:

IdentifierStart :: IdentifierStartChar
  1. 返回 IdentifierStartChar 匹配的代码点。
IdentifierPart :: IdentifierPartChar
  1. 返回 IdentifierPartChar 匹配的代码点。
UnicodeEscapeSequence :: u Hex4Digits
  1. 返回数值为 Hex4Digits 的代码点。
UnicodeEscapeSequence :: u{ CodePoint }
  1. 返回数值为 CodePoint 的代码点。

12.7.2 关键字和保留字

关键字 是一个与 IdentifierName 匹配的词法单元,但它还有一个语法用途;也就是说,它以某种语法形式出现在某些语法生成式中,例如 ifwhileasyncawait 等。

保留字 是一个不能用作标识符的 IdentifierName 。许多关键字都是保留字,但有些不是,有些仅在某些上下文中是保留的。例如 ifwhile 是保留字,await 仅在异步函数和模块中是保留的,而 async 不是保留的,它可以在变量名或语句标签中使用。

本规范使用语法生成式和 早期错误 规则的组合来指定哪些名称是有效标识符,哪些是保留字。下面列出的所有 ReservedWord ,除了 awaityield,都是无条件保留的。awaityield 的例外情况在 13.1 中进行了说明,使用了参数化的语法生成式。最后,一些早期错误规则限制了有效标识符的集合。请参阅 13.1.114.3.1.114.7.5.1 ,以及 15.7.1 。总的来说,有五类标识符名称:

  • 那些始终允许作为标识符使用的,不是关键字的名称,例如 MathwindowtoString_;

  • 那些永远不允许作为标识符使用的名称,即下面列出的 ReservedWord(除了 awaityield);

  • 那些在特定上下文中允许作为标识符使用的名称,即 awaityield;

  • 那些在 严格模式代码 中上下文不允许作为标识符使用的名称:letstaticimplementsinterfacepackageprivateprotectedpublic;

  • 那些始终允许作为标识符使用,但在某些语法生成式中的某些地方也出现为关键字的名称,即 Identifier 不允许:asasyncfromgetmetaofsettarget

术语 条件关键字上下文关键字 有时用来指在上述最后三类中的关键字,这些关键字可以在某些上下文中作为标识符使用,而在其他上下文中作为关键字使用。

语法

ReservedWord :: 之一 await break case catch class const continue debugger default delete do else enum export extends false finally for function if import in instanceof new null return super switch this throw true try typeof var void while with yield 注 1

根据 5.1.5 ,语法中的关键字匹配特定 SourceCharacter 元素的字面序列。关键字中的代码点不能通过 \ Unicode 转义序列表示。

IdentifierName 可以包含 \ UnicodeEscapeSequence ,但不能通过拼写 els\u{65} 来声明一个名为 "else" 的变量。 早期错误 规则在 13.1.1 中排除了与保留字具有相同 StringValue 的标识符。

注 2

enum 目前在本规范中不作为关键字使用。它是一个 未来保留字,为将来的语言扩展预留。

同样,implementsinterfacepackageprivateprotectedpublic严格模式代码 中是未来保留字。

注 3

名称 argumentseval 不是关键字,但在 严格模式代码 中受到一些限制。请参阅 13.1.18.6.415.2.115.5.115.6.1 ,以及 15.8.1

12.8 标点符号

语法

Punctuator :: OptionalChainingPunctuator OtherPunctuator OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit ] OtherPunctuator :: 之一 { ( ) [ ] . ... ; , < > <= >= == != === !== + - * % ** ++ -- << >> >>> & | ^ ! ~ && || ?? ? : = += -= *= %= **= <<= >>= >>>= &= |= ^= &&= ||= ??= => DivPunctuator :: / /= RightBracePunctuator :: }

12.9 字面量

12.9.1 Null 字面量

语法

NullLiteral :: null

12.9.2 布尔字面量

语法

BooleanLiteral :: true false

12.9.3 数值字面量

语法

NumericLiteralSeparator :: _ NumericLiteral :: DecimalLiteral DecimalBigIntegerLiteral NonDecimalIntegerLiteral[+Sep] NonDecimalIntegerLiteral[+Sep] BigIntLiteralSuffix LegacyOctalIntegerLiteral DecimalBigIntegerLiteral :: 0 BigIntLiteralSuffix NonZeroDigit DecimalDigits[+Sep]opt BigIntLiteralSuffix NonZeroDigit NumericLiteralSeparator DecimalDigits[+Sep] BigIntLiteralSuffix NonDecimalIntegerLiteral[Sep] :: BinaryIntegerLiteral[?Sep] OctalIntegerLiteral[?Sep] HexIntegerLiteral[?Sep] BigIntLiteralSuffix :: n DecimalLiteral :: DecimalIntegerLiteral . DecimalDigits[+Sep]opt ExponentPart[+Sep]opt . DecimalDigits[+Sep] ExponentPart[+Sep]opt DecimalIntegerLiteral ExponentPart[+Sep]opt DecimalIntegerLiteral :: 0 NonZeroDigit NonZeroDigit NumericLiteralSeparatoropt DecimalDigits[+Sep] NonOctalDecimalIntegerLiteral DecimalDigits[Sep] :: DecimalDigit DecimalDigits[?Sep] DecimalDigit [+Sep] DecimalDigits[+Sep] NumericLiteralSeparator DecimalDigit DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9 NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9 ExponentPart[Sep] :: ExponentIndicator SignedInteger[?Sep] ExponentIndicator :: one of e E SignedInteger[Sep] :: DecimalDigits[?Sep] + DecimalDigits[?Sep] - DecimalDigits[?Sep] BinaryIntegerLiteral[Sep] :: 0b BinaryDigits[?Sep] 0B BinaryDigits[?Sep] BinaryDigits[Sep] :: BinaryDigit BinaryDigits[?Sep] BinaryDigit [+Sep] BinaryDigits[+Sep] NumericLiteralSeparator BinaryDigit BinaryDigit :: one of 0 1 OctalIntegerLiteral[Sep] :: 0o OctalDigits[?Sep] 0O OctalDigits[?Sep] OctalDigits[Sep] :: OctalDigit OctalDigits[?Sep] OctalDigit [+Sep] OctalDigits[+Sep] NumericLiteralSeparator OctalDigit LegacyOctalIntegerLiteral :: 0 OctalDigit LegacyOctalIntegerLiteral OctalDigit NonOctalDecimalIntegerLiteral :: 0 NonOctalDigit LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit NonOctalDecimalIntegerLiteral DecimalDigit LegacyOctalLikeDecimalIntegerLiteral :: 0 OctalDigit LegacyOctalLikeDecimalIntegerLiteral OctalDigit OctalDigit :: one of 0 1 2 3 4 5 6 7 NonOctalDigit :: one of 8 9 HexIntegerLiteral[Sep] :: 0x HexDigits[?Sep] 0X HexDigits[?Sep] HexDigits[Sep] :: HexDigit HexDigits[?Sep] HexDigit [+Sep] HexDigits[+Sep] NumericLiteralSeparator HexDigit HexDigit :: one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

紧跟在 SourceCharacter 后面的 NumericLiteral 不能是 IdentifierStartDecimalDigit

注意

例如:3in 是错误的,而不是两个输入元素 3in

12.9.3.1 静态语义:早期错误

NumericLiteral :: LegacyOctalIntegerLiteral DecimalIntegerLiteral :: NonOctalDecimalIntegerLiteral 注意
非严格模式代码 中,这种语法是 遗留的

12.9.3.2 静态语义:MV

数值字面量表示 Number 类型BigInt 类型 的值。

12.9.3.3 静态语义:NumericValue

语法定向操作 NumericValue 不接受参数,并返回一个 Number 或 BigInt。它在以下产生式上逐段定义:

NumericLiteral :: DecimalLiteral
  1. 返回 RoundMVResult(DecimalLiteral 的 MV)。
NumericLiteral :: NonDecimalIntegerLiteral
  1. 返回 𝔽(NonDecimalIntegerLiteral 的 MV)。
NumericLiteral :: LegacyOctalIntegerLiteral
  1. 返回 𝔽(LegacyOctalIntegerLiteral 的 MV)。
NumericLiteral :: NonDecimalIntegerLiteral BigIntLiteralSuffix
  1. 返回 BigInt 值 的 MV NonDecimalIntegerLiteral
DecimalBigIntegerLiteral :: 0 BigIntLiteralSuffix
  1. 返回 0
DecimalBigIntegerLiteral :: NonZeroDigit BigIntLiteralSuffix
  1. 返回 BigInt 值 的 MV NonZeroDigit
DecimalBigIntegerLiteral :: NonZeroDigit DecimalDigits BigIntLiteralSuffix NonZeroDigit NumericLiteralSeparator DecimalDigits BigIntLiteralSuffix
  1. nDecimalDigits 中代码点的数量,排除所有 NumericLiteralSeparator 的出现。
  2. mv 为 (NonZeroDigit 的 MV × 10n) 加上 DecimalDigits 的 MV。
  3. 返回 (mv)。

12.9.4 字符串字面量

注 1

字符串字面量是用单引号或双引号括起来的 0 个或更多 Unicode 代码点。Unicode 代码点也可以通过转义序列表示。除了闭合引号的代码点、U+005C(反斜杠)、U+000D(回车符)和 U+000A(换行符)外,所有代码点都可以直接出现在字符串字面量中。任何代码点都可以以转义序列的形式出现。字符串字面量求值为 ECMAScript 字符串值。在生成这些字符串值时,Unicode 代码点按照 11.1.1 中定义的方式进行 UTF-16 编码。属于基本多文种平面的代码点编码为字符串的单个代码单元元素。所有其他代码点编码为字符串的两个代码单元元素。

语法

StringLiteral :: " DoubleStringCharactersopt " ' SingleStringCharactersopt ' DoubleStringCharacters :: DoubleStringCharacter DoubleStringCharactersopt SingleStringCharacters :: SingleStringCharacter SingleStringCharactersopt DoubleStringCharacter :: SourceCharacter but not one of " or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation SingleStringCharacter :: SourceCharacter but not one of ' or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation LineContinuation :: \ LineTerminatorSequence EscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence HexEscapeSequence UnicodeEscapeSequence CharacterEscapeSequence :: SingleEscapeCharacter NonEscapeCharacter SingleEscapeCharacter :: one of ' " \ b f n r t v NonEscapeCharacter :: SourceCharacter but not one of EscapeCharacter or LineTerminator EscapeCharacter :: SingleEscapeCharacter DecimalDigit x u LegacyOctalEscapeSequence :: 0 [lookahead ∈ { 8, 9 }] NonZeroOctalDigit [lookahead ∉ OctalDigit] ZeroToThree OctalDigit [lookahead ∉ OctalDigit] FourToSeven OctalDigit ZeroToThree OctalDigit OctalDigit NonZeroOctalDigit :: OctalDigit but not 0 ZeroToThree :: one of 0 1 2 3 FourToSeven :: one of 4 5 6 7 NonOctalDecimalEscapeSequence :: one of 8 9 HexEscapeSequence :: x HexDigit HexDigit UnicodeEscapeSequence :: u Hex4Digits u{ CodePoint } Hex4Digits :: HexDigit HexDigit HexDigit HexDigit

非终结符 HexDigit 的定义见 12.9.3SourceCharacter11.1 中定义。

注 2

<LF> 和 <CR> 不能出现在字符串字面量中,除非作为 LineContinuation 的一部分以产生空代码点序列。在字符串字面量的字符串值中包含它们的正确方法是使用转义序列,如 \n\u000A

12.9.4.1 静态语义:早期错误

EscapeSequence :: LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence 注 1
非严格代码 中,此语法是 遗留的
注 2

字符串字面量可能会出现在将包围代码置于 严格模式 中的 使用严格指令 之前,实施时必须注意对这些字面量执行上述规则。例如,以下源文本包含一个语法错误:

function invalid() { "\7"; "use strict"; }

12.9.4.2 静态语义:SV

语法定向操作 SV 不接受参数,并返回一个字符串。

字符串字面量表示 字符串类型 的值。SV 通过递归应用字符串字面量的各个部分来生成字符串值。在这个过程中,字符串字面量中的一些 Unicode 代码点被解释为具有 数学值,如下所述或在 12.9.3 中描述。

表 38: 字符串单字符转义序列
转义序列 代码单元值 Unicode 字符名称 符号
\b 0x0008 退格符 <BS>
\t 0x0009 字符制表符 <HT>
\n 0x000A 换行符 (LF) <LF>
\v 0x000B 行制表符 <VT>
\f 0x000C 换页符 (FF) <FF>
\r 0x000D 回车符 (CR) <CR>
\" 0x0022 引号 "
\' 0x0027 撇号 '
\\ 0x005C 反斜杠 \

12.9.4.3 静态语义:MV

12.9.5 正则表达式字面量

注 1

正则表达式字面量是一个输入元素,每次评估该字面量时都会转换为一个 RegExp 对象(参见 22.2)。程序中的两个正则表达式字面量评估为永远不会相互比较为 === 的正则表达式对象,即使这两个字面量的内容相同。也可以通过 new RegExp 或调用 RegExp 构造函数 在运行时创建 RegExp 对象(参见 22.2.4)。

下面的生成式描述了正则表达式字面量的语法,并由输入元素扫描器用于查找正则表达式字面量的结束位置。包含 RegularExpressionBodyRegularExpressionFlags 的源文本随后使用更严格的 ECMAScript 正则表达式语法再次解析(参见 22.2.1)。

实现可以扩展 22.2.1 中定义的 ECMAScript 正则表达式语法,但不得扩展下面定义的 RegularExpressionBodyRegularExpressionFlags 生成式或这些生成式使用的生成式。

语法

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags RegularExpressionBody :: RegularExpressionFirstChar RegularExpressionChars RegularExpressionChars :: [empty] RegularExpressionChars RegularExpressionChar RegularExpressionFirstChar :: RegularExpressionNonTerminator 但不包括 *\/[ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionChar :: RegularExpressionNonTerminator 但不包括 \/[ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionBackslashSequence :: \ RegularExpressionNonTerminator RegularExpressionNonTerminator :: SourceCharacter 但不包括 LineTerminator RegularExpressionClass :: [ RegularExpressionClassChars ] RegularExpressionClassChars :: [empty] RegularExpressionClassChars RegularExpressionClassChar RegularExpressionClassChar :: RegularExpressionNonTerminator 但不包括 ]\ RegularExpressionBackslashSequence RegularExpressionFlags :: [empty] RegularExpressionFlags IdentifierPartChar 注 2

正则表达式字面量不能为空;而不是表示一个空的正则表达式字面量,代码单元序列 // 启动一个单行注释。要指定一个空的正则表达式,请使用:/(?:)/

12.9.5.1 静态语义:BodyText

语法导向操作 BodyText 不接受任何参数并返回源文本。它分段定义于以下生成式:

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags
  1. 返回被识别为 RegularExpressionBody 的源文本。

12.9.5.2 静态语义:FlagText

语法导向操作 FlagText 不接受任何参数并返回源文本。它分段定义于以下生成式:

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags
  1. 返回被识别为 RegularExpressionFlags 的源文本。

12.9.6 模板字面量词法组件

语法

Template :: NoSubstitutionTemplate TemplateHead NoSubstitutionTemplate :: ` TemplateCharactersopt ` TemplateHead :: ` TemplateCharactersopt ${ TemplateSubstitutionTail :: TemplateMiddle TemplateTail TemplateMiddle :: } TemplateCharactersopt ${ TemplateTail :: } TemplateCharactersopt ` TemplateCharacters :: TemplateCharacter TemplateCharactersopt TemplateCharacter :: $ [lookahead ≠ {] \ TemplateEscapeSequence \ NotEscapeSequence LineContinuation LineTerminatorSequence SourceCharacter 但不包括 `\$LineTerminator TemplateEscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] HexEscapeSequence UnicodeEscapeSequence NotEscapeSequence :: 0 DecimalDigit DecimalDigit 但不包括0 x [lookahead ∉ HexDigit] x HexDigit [lookahead ∉ HexDigit] u [lookahead ∉ HexDigit] [lookahead ≠ {] u HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit HexDigit [lookahead ∉ HexDigit] u { [lookahead ∉ HexDigit] u { NotCodePoint [lookahead ∉ HexDigit] u { CodePoint [lookahead ∉ HexDigit] [lookahead ≠ }] NotCodePoint :: HexDigits[~Sep] 但只有当 HexDigits 的 MV > 0x10FFFF 时 CodePoint :: HexDigits[~Sep] 但只有当 HexDigits 的 MV ≤ 0x10FFFF 时

TemplateSubstitutionTailInputElementTemplateTail 替代词法目标使用。

12.9.6.1 静态语义:TV

语法导向操作 TV 不接受参数并返回字符串或undefined。模板字面量组件由 TV 解释为 字符串类型 的值。TV 用于构造模板对象的索引组件(俗称模板值)。在 TV 中,转义序列由转义序列表示的 Unicode 代码点的 UTF-16 代码单元替换。

12.9.6.2 静态语义:TRV

语法导向操作 TRV 不接受参数并返回字符串。模板字面量组件由 TRV 解释为字符串类型的值。TRV 用于构造模板对象的原始组件(俗称模板原始值)。TRV 类似于TV,区别在于 TRV 中的转义序列按字面意思解释。

TV排除了LineContinuation的代码单元,而 TRV 包括它们。 <CR><LF> 和 <CR>LineTerminatorSequence 被标准化为 TV 和 TRV 的 <LF>。需要明确的TemplateEscapeSequence包括 <CR> 或 <CR><LF> 序列。

12.10 自动分号插入

大多数 ECMAScript 语句和声明必须以分号结尾。这些分号总是可以显式出现在源代码中。然而,为了方便,在某些情况下,这些分号可以从源代码中省略。在这些情况下,可以通过描述分号自动插入到源代码令牌流中的那些情况来解释。

12.10.1 自动分号插入规则

在以下规则中,“令牌”是指使用当前词法 目标符号确定的实际识别的词法令牌,如 第 12条款所述。

分号插入有三条基本规则:

  1. 当从左到右解析源文本时,遇到不允许的令牌(称为冒犯令牌)时,如果以下条件之一为真, 则会在冒犯令牌之前自动插入分号:

    • 冒犯令牌与前一个令牌之间至少有一个 行终止符分隔。
    • 冒犯令牌是}
    • 前一个令牌是),插入的分号将被解析为do-while语句的终止分号 ( 14.7.2)。
  2. 当从左到右解析源文本时,遇到输入令牌流的结尾并且解析器无法将输入令牌流解析为目标非终结符的单个实例时, 则在输入流的结尾自动插入分号。
  3. 当从左到右解析源文本时,遇到某些语法规则允许的令牌,但该语法规则是受限规则,并且该令牌是紧跟在标注 “[no 行终止符 here]”之后的受限规则中的第一个令牌 (因此称为受限令牌),并且受限令牌与前一个令牌之间至少有一个 行终止符分隔时, 则在受限令牌之前自动插入分号。

但是,前述规则有一个额外的优先条件:如果分号将被解析为空语句或成为for语句头中的两个分号之一, 则不会自动插入分号(见 14.7.4)。

以下是语法中唯一的受限规则:

UpdateExpression [Yield, Await] : LeftHandSideExpression [?Yield, ?Await] [no 行终止符 here] ++ LeftHandSideExpression [?Yield, ?Await] [no 行终止符 here] -- ContinueStatement [Yield, Await] : continue ; continue [no 行终止符 here] LabelIdentifier [?Yield, ?Await] ; BreakStatement [Yield, Await] : break ; break [no 行终止符 here] LabelIdentifier [?Yield, ?Await] ; ReturnStatement [Yield, Await] : return ; return [no 行终止符 here] Expression [+In, ?Yield, ?Await] ; ThrowStatement [Yield, Await] : throw [no 行终止符 here] Expression [+In, ?Yield, ?Await] ; YieldExpression [In, Await] : yield yield [no 行终止符 here] AssignmentExpression [?In, +Yield, ?Await] yield [no 行终止符 here] * AssignmentExpression [?In, +Yield, ?Await] ArrowFunction [In, Yield, Await] : ArrowParameters [?Yield, ?Await] [no 行终止符 here] => ConciseBody [?In] AsyncFunctionDeclaration [Yield, Await, Default] : async [no 行终止符 here] function BindingIdentifier [?Yield, ?Await] ( FormalParameters [~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [no 行终止符 here] function ( FormalParameters [~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [no 行终止符 here] function BindingIdentifier [~Yield, +Await]opt ( FormalParameters [~Yield, +Await] ) { AsyncFunctionBody } AsyncMethod [Yield, Await] : async [no 行终止符 here] ClassElementName [?Yield, ?Await] ( UniqueFormalParameters [~Yield, +Await] ) { AsyncFunctionBody } AsyncGeneratorDeclaration [Yield, Await, Default] : async [no 行终止符 here] function * BindingIdentifier [?Yield, ?Await] ( FormalParameters [+Yield, +Await] ) { AsyncGeneratorBody } [+Default] async [no 行终止符 here] function * ( FormalParameters [+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorExpression : async [no 行终止符 here] function * BindingIdentifier [+Yield, +Await]opt ( FormalParameters [+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorMethod [Yield, Await] : async [no 行终止符 here] * ClassElementName [?Yield, ?Await] ( UniqueFormalParameters [+Yield, +Await] ) { AsyncGeneratorBody } AsyncArrowFunction [In, Yield, Await] : async [no 行终止符 here] AsyncArrowBindingIdentifier [?Yield] [no 行终止符 here] => AsyncConciseBody [?In] CoverCallExpressionAndAsyncArrowHead [?Yield, ?Await] [no 行终止符 here] => AsyncConciseBody [?In] AsyncArrowHead : async [no 行终止符 here] ArrowFormalParameters [~Yield, +Await]

这些受限规则的实际效果如下:

  • 当遇到++--令牌且解析器将其视为后缀操作符,并且前一个令牌与++--令牌之间至少有一个 行终止符时, 则在++--令牌之前自动插入分号。
  • 当遇到continuebreakreturnthrowyield令牌并且在下一个令牌之前遇到一个 行终止符时, 则在continuebreakreturnthrowyield令牌之后自动插入分号。
  • 当箭头函数的参数之后有一个 行终止符且在=> 令牌之前时,自动插入分号并且标点符号会导致语法错误。
  • async令牌之后有一个 行终止符且在 function 标识符名称(令牌之前时,自动插入分号并且async令牌不会被视为与后续令牌相同的表达式或类元素。
  • async令牌之后有一个 行终止符且在 *令牌之前时,自动插入分号并且标点符号会导致语法错误。

因此,对ECMAScript程序员的实际建议是:

  • 后缀++--操作符应与其操作数在同一行。
  • returnthrow语句中的 表达式或在 yield表达式中的 赋值表达式应从 returnthrowyield令牌所在的同一行开始。
  • breakcontinue语句中的 标签标识符应与 breakcontinue令牌在同一行。
  • 箭头函数参数的结束与=>应在同一行。
  • 异步函数或方法前的async令牌应与紧随其后的令牌在同一行。

12.10.2 自动分号插入的示例

本节为非规范性内容。

以下源代码

{ 1 2 } 3

即使使用自动分号插入规则,也不是 ECMAScript 语法中的有效句子。相反,以下源代码

{ 1
2 } 3

也不是有效的 ECMAScript 句子,但通过自动分号插入会被转换为以下内容:

{ 1
;2 ;} 3;

这是一个有效的 ECMAScript 句子。

以下源代码

for (a; b
)

不是有效的 ECMAScript 句子,且不会因自动分号插入而改变,因为 for 语句头部需要的分号。自动分号插入永远不会插入 for 语句头部的两个分号之一。

以下源代码

return
a + b

通过自动分号插入会被转换为以下内容:

return;
a + b;
注 1

表达式 a + b 不会被视为 return 语句要返回的值,因为 returna + b 之间有一个 行终止符 分隔。

以下源代码

a = b
++c

通过自动分号插入会被转换为以下内容:

a = b;
++c;
注 2

符号 ++ 不会被视为应用于变量 b 的后缀运算符,因为 b++ 之间有一个 行终止符

以下源代码

if (a > b)
else c = d

不是有效的 ECMAScript 句子,且即使在 else 符号之前没有任何语法规则适用,自动分号插入也不会改变,因为自动插入的分号会被解析为一个空语句。

以下源代码

a = b + c
(d + e).print()

不会被自动分号插入规则改变,因为第二行开始的括号表达式可以被解释为函数调用的参数列表:

a = b + c(d + e).print()

在赋值语句必须以左括号开始的情况下,程序员最好在前一条语句的末尾提供一个显式分号,而不是依赖自动分号插入。

12.10.3 自动分号插入的有趣案例

本节为非规范性内容。

ECMAScript 程序可以通过依赖自动分号插入来以很少分号的风格编写。如上所述,分号并不会在每个换行处插入,自动分号插入可能依赖跨行终止符的多个标记。

随着新的语法特性被添加到 ECMAScript 中,可能会增加一些语法产生式,这会导致依赖自动分号插入的行在解析时改变语法产生式。

在本节的目的中,如果某个地方的分号是否插入取决于之前的源文本,则该自动分号插入的案例被认为是有趣的。本节的其余部分描述了 ECMAScript 这一版本中一些有趣的自动分号插入案例。

12.10.3.1 语句列表中自动分号插入的有趣案例

在一个 StatementList 中,许多 StatementListItem 以分号结束,这些分号可以通过自动分号插入省略。由于上述规则,在表达式结束的一行末尾,如果下一行以以下任意内容开始,则需要一个分号:

  • 开括号 (()。没有分号,这两行会被视为一个 CallExpression
  • 开方括号 ([)。没有分号,这两行会被视为属性访问,而不是一个 ArrayLiteralArrayAssignmentPattern
  • 模板字符串 (`)。没有分号,这两行会被解释为一个标记模板 (13.3.11),前一个表达式作为 MemberExpression
  • 一元 +-。没有分号,这两行会被解释为使用对应的二元运算符。
  • 正则表达式文字。没有分号,这两行可能会被解析为 / MultiplicativeOperator,例如如果正则表达式有标志。

12.10.3.2 自动分号插入和“[无 行终止符 这里]”的案例

本节为非规范性内容。

ECMAScript 包含一些语法产生式,它们包括“[无 行终止符 这里]”。这些产生式有时是为了在语法中拥有可选操作数。在这些位置引入 行终止符 会通过使用没有可选操作数的语法产生式来改变源文本的语法产生式。

本节的其余部分描述了 ECMAScript 这一版本中使用“[无 行终止符 这里]”的若干产生式。

12.10.3.2.1 带有可选操作数和“[无 行终止符 这里]”的语法产生式列表

13 ECMAScript 语言:表达式

13.1 标识符

语法

IdentifierReference[Yield, Await] : Identifier [~Yield] yield [~Await] await BindingIdentifier[Yield, Await] : Identifier yield await LabelIdentifier[Yield, Await] : Identifier [~Yield] yield [~Await] await Identifier : IdentifierName but not ReservedWord 注意

yieldawait 在语法中允许作为 BindingIdentifier,但在下面的 静态语义 中禁止,以防止在某些情况下自动插入分号,例如

let
        await 0;

13.1.1 静态语义:早期错误

BindingIdentifier : Identifier IdentifierReference : yield BindingIdentifier : yield LabelIdentifier : yield IdentifierReference : await BindingIdentifier : await LabelIdentifier : await BindingIdentifier[Yield, Await] : yield
  • 如果该生成式有一个 [Yield] 参数,那么这是一个语法错误。
BindingIdentifier[Yield, Await] : await
  • 如果该生成式有一个 [Await] 参数,那么这是一个语法错误。
IdentifierReference[Yield, Await] : Identifier BindingIdentifier[Yield, Await] : Identifier LabelIdentifier[Yield, Await] : Identifier
  • 如果该生成式有一个 [Yield] 参数,并且 StringValueIdentifier"yield",那么这是一个语法错误。
  • 如果该生成式有一个 [Await] 参数,并且 StringValueIdentifier"await",那么这是一个语法错误。
Identifier : IdentifierName 但不是 ReservedWord 注意

StringValueIdentifierName 标准化了 IdentifierName 中的任何 Unicode 转义序列,因此这些转义不能用于编写与 Identifier 的代码点序列相同的 ReservedWord

13.1.2 静态语义:StringValue

语法导向操作 StringValue 不带参数并返回一个字符串。它分段定义在以下生成式中:

IdentifierName :: IdentifierStart IdentifierName IdentifierPart
  1. idTextUnescapedIdentifierCodePointsIdentifierName
  2. 返回 CodePointsToString(idTextUnescaped)。
IdentifierReference : yield BindingIdentifier : yield LabelIdentifier : yield
  1. 返回 "yield"
IdentifierReference : await BindingIdentifier : await LabelIdentifier : await
  1. 返回 "await"
Identifier : IdentifierName 但不是 ReservedWord
  1. 返回 StringValueIdentifierName
PrivateIdentifier :: # IdentifierName
  1. 返回 0x0023(数字符号)和 StringValueIdentifierName字符串连接
ModuleExportName : StringLiteral
  1. 返回 SVStringLiteral

13.1.3 运行时语义:评估

IdentifierReference : Identifier
  1. 返回 ? ResolveBinding(StringValueIdentifier)。
IdentifierReference : yield
  1. 返回 ? ResolveBinding("yield")。
IdentifierReference : await
  1. 返回 ? ResolveBinding("await")。
注 1

评估 IdentifierReference 的结果总是类型为引用的值。

注 2

非严格模式代码中,关键字yield 可以用作标识符。评估 IdentifierReference 时将 yield 解析为 Identifier。早期错误限制确保这种评估仅在 非严格模式代码中发生。

13.2 主要表达式

语法

PrimaryExpression[Yield, Await] : this IdentifierReference[?Yield, ?Await] Literal ArrayLiteral[?Yield, ?Await] ObjectLiteral[?Yield, ?Await] FunctionExpression ClassExpression[?Yield, ?Await] GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral[?Yield, ?Await, ~Tagged] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[Yield, Await] : ( Expression[+In, ?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ) ( ) ( ... BindingIdentifier[?Yield, ?Await] ) ( ... BindingPattern[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingIdentifier[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingPattern[?Yield, ?Await] )

补充语法

当处理如下产生式实例时
PrimaryExpression[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
CoverParenthesizedExpressionAndArrowParameterList 的解释会使用以下语法进行细化:

ParenthesizedExpression[Yield, Await] : ( Expression[+In, ?Yield, ?Await] )

13.2.1 this 关键字

13.2.1.1 运行时语义:求值

PrimaryExpression : this
  1. 返回 ? ResolveThisBinding().

13.2.2 标识符引用

关于IdentifierReference,请参阅 13.1

13.2.3 字面量

语法

Literal : NullLiteral BooleanLiteral NumericLiteral StringLiteral

13.2.3.1 运行时语义:求值

Literal : NullLiteral
  1. 返回 null
Literal : BooleanLiteral
  1. 如果 BooleanLiteral 是标记 false,返回 false
  2. 如果 BooleanLiteral 是标记 true,返回 true
Literal : NumericLiteral
  1. 返回 NumericValueNumericLiteral,如 12.9.3 中定义。
Literal : StringLiteral
  1. 返回 SVStringLiteral,如 12.9.4.2 中定义。

13.2.4 数组初始化器

注意

ArrayLiteral 是描述数组初始化的表达式,使用一个列表,其中包含零个或多个表达式,每个表达式代表一个数组元素,并用方括号括起来。这些元素不必是字面量;它们在每次数组初始化器被求值时都会被求值。

数组元素可以在元素列表的开头、中间或结尾省略。每当元素列表中的逗号前没有 AssignmentExpression(即开头的逗号或另一个逗号之后的逗号)时,缺失的数组元素将贡献数组的长度并增加后续元素的索引。省略的数组元素是未定义的。如果在数组末尾省略一个元素,该元素不会贡献数组的长度。

语法

ArrayLiteral[Yield, Await] : [ Elisionopt ] [ ElementList[?Yield, ?Await] ] [ ElementList[?Yield, ?Await] , Elisionopt ] ElementList[Yield, Await] : Elisionopt AssignmentExpression[+In, ?Yield, ?Await] Elisionopt> SpreadElement[?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt AssignmentExpression[+In, ?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt SpreadElement[?Yield, ?Await] Elision : , Elision , SpreadElement[Yield, Await] : ... AssignmentExpression[+In, ?Yield, ?Await]

13.2.4.1 运行时语义:数组积累

语法定向操作 ArrayAccumulation 接受参数 array(一个数组)和 nextIndex(一个整数)并返回正常完成记录包含的一个整数或一个中断完成记录。它根据以下产生式逐步定义:

Elision : ,
  1. lennextIndex + 1。
  2. 执行 ? Set(array, "length",𝔽(len), true)。
  3. 注意:如果 len 超过 232 - 1,则上述步骤会抛出错误。
  4. 返回 len
Elision : Elision ,
  1. 返回 ? ArrayAccumulation of Elision with arguments array and (nextIndex + 1)。
ElementList : Elisionopt AssignmentExpression
  1. 如果 Elision 存在,则
    1. 设置 nextIndex 为 ? ArrayAccumulation of Elision with arguments array and nextIndex
  2. initResult 为 ? Evaluation of AssignmentExpression
  3. initValue 为 ? GetValue(initResult)。
  4. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), initValue)。
  5. 返回 nextIndex + 1。
ElementList : Elisionopt SpreadElement
  1. 如果 Elision 存在,则
    1. 设置 nextIndex 为 ? ArrayAccumulation of Elision with arguments array and nextIndex
  2. 返回 ? ArrayAccumulation of SpreadElement with arguments array and nextIndex
SpreadElement : ... AssignmentExpression
  1. spreadRef 为 ? Evaluation of AssignmentExpression
  2. spreadObj 为 ? GetValue(spreadRef)。
  3. iteratorRecord 为 ? GetIterator(spreadObj, sync)。
  4. 重复,
    1. next 为 ? IteratorStepValue(iteratorRecord)。
    2. 如果 nextdone,返回 nextIndex
    3. 执行 ! CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), next)。
    4. 设置 nextIndexnextIndex + 1。
注意

CreateDataPropertyOrThrow 用于确保定义数组的自有属性,即使标准内置数组原型对象已被修改以阻止使用 [[Set]] 创建新自有属性。

13.2.4.2 运行时语义:求值

ArrayLiteral : [ Elisionopt ]
  1. array 为 ! ArrayCreate(0)。
  2. 如果 Elision 存在,则
    1. 执行 ? ArrayAccumulation of Elision with arguments array and 0。
  3. 返回 array
ArrayLiteral : [ ElementList ]
  1. array 为 ! ArrayCreate(0)。
  2. 执行 ? ArrayAccumulation of ElementList with arguments array and 0。
  3. 返回 array
ArrayLiteral : [ ElementList , Elisionopt ]
  1. array 为 ! ArrayCreate(0)。
  2. nextIndex 为 ? ArrayAccumulation of ElementList with arguments array and 0。
  3. 如果 Elision 存在,则
    1. 执行 ? ArrayAccumulation of Elision with arguments array and nextIndex
  4. 返回 array

13.2.5 对象初始化器

注1

对象初始化器是一个描述对象初始化的表达式,写成类似字面量的形式。它是一个由零个或多个属性键和关联值组成的列表,用大括号括起来。值不必是字面量;每次对象初始化器求值时,它们都会被求值。

语法

ObjectLiteral[Yield, Await] : { } { PropertyDefinitionList[?Yield, ?Await] } { PropertyDefinitionList[?Yield, ?Await] , } PropertyDefinitionList[Yield, Await] : PropertyDefinition[?Yield, ?Await] PropertyDefinitionList[?Yield, ?Await] , PropertyDefinition[?Yield, ?Await] PropertyDefinition[Yield, Await] : IdentifierReference[?Yield, ?Await] CoverInitializedName[?Yield, ?Await] PropertyName[?Yield, ?Await] : AssignmentExpression[+In, ?Yield, ?Await] MethodDefinition[?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] PropertyName[Yield, Await] : LiteralPropertyName ComputedPropertyName[?Yield, ?Await] LiteralPropertyName : IdentifierName StringLiteral NumericLiteral ComputedPropertyName[Yield, Await] : [ AssignmentExpression[+In, ?Yield, ?Await] ] CoverInitializedName[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await] Initializer[In, Yield, Await] : = AssignmentExpression[?In, ?Yield, ?Await] 注2

MethodDefinition15.4中定义。

注3

在某些上下文中,ObjectLiteral用作更受限的二级语法的覆盖语法。CoverInitializedName生产是必要的,以完全覆盖这些二级语法。但是,在需要实际ObjectLiteral的正常上下文中使用此生产会导致早期语法错误。

13.2.5.1 静态语义:早期错误

PropertyDefinition : MethodDefinition

除了描述实际的对象初始化器外,ObjectLiteral生产还用作ObjectAssignmentPattern的覆盖语法,并且可能被识别为CoverParenthesizedExpressionAndArrowParameterList的一部分。当ObjectLiteral出现在需要ObjectAssignmentPattern的上下文中时,不适用以下早期错误规则。此外,在最初解析CoverParenthesizedExpressionAndArrowParameterListCoverCallExpressionAndAsyncArrowHead时也不适用。

PropertyDefinition : CoverInitializedName
  • 如果任何源文本与此生产匹配,则这是语法错误。
注1

此生产的存在是为了使ObjectLiteral可以用作ObjectAssignmentPattern的覆盖语法。它不能出现在实际的对象初始化器中。

ObjectLiteral : { PropertyDefinitionList } { PropertyDefinitionList , } 注2

列表返回的PropertyNameList不包括使用ComputedPropertyName定义的属性名称。

13.2.5.2 静态语义:IsComputedPropertyKey

语法指向操作 IsComputedPropertyKey不带参数,返回一个布尔值。它在以下生成中逐段定义:

PropertyName : LiteralPropertyName
  1. 返回false
PropertyName : ComputedPropertyName
  1. 返回true

13.2.5.3 静态语义:PropertyNameList

语法指向操作 PropertyNameList不带参数,返回一个字符串的列表。它在以下生成中逐段定义:

PropertyDefinitionList : PropertyDefinition
  1. propName成为PropName of PropertyDefinition
  2. 如果propNameempty,则返回一个新的空列表
  3. 返回« propName »。
PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. list成为PropertyNameList of PropertyDefinitionList
  2. propName成为PropName of PropertyDefinition
  3. 如果propNameempty,则返回list
  4. 返回列表连接 of list和« propName »。

13.2.5.4 运行时语义:求值

ObjectLiteral : { }
  1. 返回OrdinaryObjectCreate(%Object.prototype%)。
ObjectLiteral : { PropertyDefinitionList } { PropertyDefinitionList , }
  1. obj成为OrdinaryObjectCreate(%Object.prototype%)。
  2. PropertyDefinitionList执行PropertyDefinitionEvaluation,参数为obj
  3. 返回obj
LiteralPropertyName : IdentifierName
  1. 返回StringValue of IdentifierName
LiteralPropertyName : StringLiteral
  1. 返回SV of StringLiteral
LiteralPropertyName : NumericLiteral
  1. nbr成为NumericValue of NumericLiteral
  2. 返回!ToString(nbr)。
ComputedPropertyName : [ AssignmentExpression ]
  1. exprValue成为Evaluation of AssignmentExpression
  2. propName成为GetValue(exprValue)。
  3. 返回ToPropertyKey(propName)。

13.2.5.5 运行时语义:PropertyDefinitionEvaluation

语法指向操作 PropertyDefinitionEvaluation接受参数object(一个对象)并返回normal completion containingunused或一个abrupt completion。它在以下生成中逐段定义:

PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. PropertyDefinitionList执行PropertyDefinitionEvaluation,参数为object
  2. PropertyDefinition执行PropertyDefinitionEvaluation,参数为object
  3. 返回unused
PropertyDefinition : ... AssignmentExpression
  1. exprValue成为Evaluation of AssignmentExpression
  2. fromValue成为GetValue(exprValue)。
  3. excludedNames成为一个新的空列表
  4. objectfromValueexcludedNames执行CopyDataProperties
  5. 返回unused
PropertyDefinition : IdentifierReference
  1. propName成为StringValue of IdentifierReference
  2. exprValue成为Evaluation of IdentifierReference
  3. propValue成为GetValue(exprValue)。
  4. 断言object是一个普通的、可扩展的对象,没有不可配置的属性。
  5. objectpropNamepropValue执行CreateDataPropertyOrThrow
  6. 返回unused
PropertyDefinition : PropertyName : AssignmentExpression
  1. propKey成为Evaluation of PropertyName
  2. 如果此PropertyDefinition包含在一个Script中,并且正在为JSON.parse求值(请参阅7 of JSON.parse),则
    1. isProtoSetter成为false
  3. 否则,如果propKey__proto__并且IsComputedPropertyKey of PropertyNamefalse,则
    1. isProtoSetter成为true
  4. 否则,
    1. isProtoSetter成为false
  5. 如果IsAnonymousFunctionDefinition of AssignmentExpressiontrue并且isProtoSetterfalse,则
    1. propValue成为NamedEvaluation of AssignmentExpression with argument propKey
  6. 否则,
    1. exprValueRef成为Evaluation of AssignmentExpression
    2. propValue成为GetValue(exprValueRef)。
  7. 如果isProtoSettertrue,则
    1. 如果propValue一个对象propValuenull,则
      1. 执行!object.[[SetPrototypeOf]](propValue)。
    2. 返回unused
  8. 断言object是一个普通的、可扩展的对象,没有不可配置的属性。
  9. objectpropKeypropValue执行CreateDataPropertyOrThrow
  10. 返回unused
PropertyDefinition : MethodDefinition
  1. MethodDefinition执行MethodDefinitionEvaluation,参数为objecttrue
  2. 返回unused

13.2.6 函数定义表达式

参见15.2了解 PrimaryExpression : FunctionExpression

参见15.5了解 PrimaryExpression : GeneratorExpression

参见15.7了解 PrimaryExpression : ClassExpression

参见15.8了解 PrimaryExpression : AsyncFunctionExpression

参见15.6了解 PrimaryExpression : AsyncGeneratorExpression

13.2.7 正则表达式字面量

语法

参见12.9.5

13.2.7.1 静态语义:早期错误

PrimaryExpression : RegularExpressionLiteral

13.2.7.2 静态语义:IsValidRegularExpressionLiteral(literal)

抽象操作IsValidRegularExpressionLiteral接受参数literal(一个RegularExpressionLiteral Parse Node)并返回一个布尔值。它在调用时执行以下步骤以确定其参数是否为有效的正则表达式字面量:

  1. flagsFlagTextliteral
  2. 如果flags包含dgimsuvy之外的任何代码点,或flags包含的任何代码点不止一次,则返回false
  3. 如果flags包含u,则令utrue;否则令ufalse
  4. 如果flags包含v,则令vtrue;否则令vfalse
  5. patternTextBodyTextliteral
  6. 如果ufalsevfalse,则
    1. stringValueCodePointsToString(patternText)。
    2. patternText设置为解释stringValue的每个16位元素为Unicode BMP代码点而得到的代码点序列。不对元素应用UTF-16解码。
  7. parseResultParsePattern(patternText, u, v)。
  8. 如果parseResult是一个Parse Node,则返回true;否则返回false

13.2.7.3 运行时语义:求值

PrimaryExpression : RegularExpressionLiteral
  1. patternCodePointsToString(BodyTextRegularExpressionLiteral)。
  2. flagsCodePointsToString(FlagTextRegularExpressionLiteral)。
  3. 返回!RegExpCreate(pattern, flags)。

13.2.8 模板字面量

语法

TemplateLiteral[Yield, Await, Tagged] : NoSubstitutionTemplate SubstitutionTemplate[?Yield, ?Await, ?Tagged] SubstitutionTemplate[Yield, Await, Tagged] : TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged] TemplateSpans[Yield, Await, Tagged] : TemplateTail TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateTail TemplateMiddleList[Yield, Await, Tagged] : TemplateMiddle Expression[+In, ?Yield, ?Await] TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await]

13.2.8.1 静态语义: 早期错误

TemplateLiteral [Yield, Await, Tagged] : NoSubstitutionTemplate TemplateLiteral [Yield, Await, Tagged] : SubstitutionTemplate [?Yield, ?Await, ?Tagged]
  • 如果 TemplateStrings 的结果中元素的数量大于或等于 232,则这是一个语法错误。
SubstitutionTemplate [Yield, Await, Tagged] : TemplateHead Expression [+In, ?Yield, ?Await] TemplateSpans [?Yield, ?Await, ?Tagged] TemplateSpans [Yield, Await, Tagged] : TemplateTail TemplateMiddleList [Yield, Await, Tagged] : TemplateMiddle Expression [+In, ?Yield, ?Await] TemplateMiddleList [?Yield, ?Await, ?Tagged] TemplateMiddle Expression [+In, ?Yield, ?Await]

13.2.8.2 静态语义:模板字符串

模板字符串是一个语法导向操作,它接受参数raw(一个布尔值)并返回一个 列表,其中包含字符串或undefined。它在以下产生式上分段定义:

TemplateLiteral : NoSubstitutionTemplate
  1. 返回 « TemplateString(NoSubstitutionTemplate, raw) ».
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. head 为 « TemplateString(TemplateHead, raw) ».
  2. tailTemplateStrings of TemplateSpans with argument raw.
  3. 返回 headtail列表连接.
TemplateSpans : TemplateTail
  1. 返回 « TemplateString(TemplateTail, raw) ».
TemplateSpans : TemplateMiddleList TemplateTail
  1. middleTemplateStrings of TemplateMiddleList with argument raw.
  2. tail 为 « TemplateString(TemplateTail, raw) ».
  3. 返回 middletail列表连接.
TemplateMiddleList : TemplateMiddle Expression
  1. 返回 « TemplateString(TemplateMiddle, raw) ».
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. frontTemplateStrings of TemplateMiddleList with argument raw.
  2. last 为 « TemplateString(TemplateMiddle, raw) ».
  3. 返回 frontlast列表连接.

13.2.8.3 静态语义:TemplateString ( templateToken, raw )

抽象操作 TemplateString 接受参数 templateToken(一个 NoSubstitutionTemplate 解析节点,一个 TemplateHead 解析节点,一个 TemplateMiddle 解析节点,或一个 TemplateTail 解析节点)和 raw(一个布尔值),并返回一个字符串或 undefined。它在被调用时执行以下步骤:

  1. 如果 rawtrue,则
    1. stringtemplateTokenTRV
  2. 否则,
    1. stringtemplateTokenTV
  3. 返回 string
注意

如果 rawfalse 并且 templateToken 包含一个 NotEscapeSequence,则此操作返回 undefined。在所有其他情况下,它返回一个字符串。

13.2.8.4 GetTemplateObject ( templateLiteral )

抽象操作 GetTemplateObject 接受参数 templateLiteral(一个 解析节点)并返回一个数组。它在被调用时执行以下步骤:

  1. realm当前领域记录
  2. templateRegistryrealm.[[TemplateMap]]
  3. 对于 templateRegistry 中的每个元素 e,执行
    1. 如果 e.[[Site]]templateLiteral 相同的解析节点,则
      1. 返回 e.[[Array]]
  4. rawStringsTemplateStrings of templateLiteral with argument true
  5. 断言rawStrings 是一个 字符串列表
  6. cookedStringsTemplateStrings of templateLiteral with argument false
  7. countcookedStrings 的元素数量。
  8. 断言count ≤ 232 - 1。
  9. template 为 ! ArrayCreate(count)。
  10. rawObj 为 ! ArrayCreate(count)。
  11. index 为 0。
  12. 重复,当 index < count 时,
    1. prop 为 ! ToString(𝔽(index))。
    2. cookedValuecookedStrings[index]。
    3. 执行 ! DefinePropertyOrThrow(template, prop, PropertyDescriptor { [[Value]]: cookedValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false })。
    4. rawValue 为字符串值 rawStrings[index]。
    5. 执行 ! DefinePropertyOrThrow(rawObj, prop, PropertyDescriptor { [[Value]]: rawValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false })。
    6. indexindex + 1。
  13. 执行 ! SetIntegrityLevel(rawObj, frozen)。
  14. 执行 ! DefinePropertyOrThrow(template, "raw", PropertyDescriptor { [[Value]]: rawObj, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。
  15. 执行 ! SetIntegrityLevel(template, frozen)。
  16. 将记录 { [[Site]]: templateLiteral, [[Array]]: template } 追加到 realm.[[TemplateMap]]
  17. 返回 template
注意 1

模板对象的创建不会导致 异常完成

注意 2

程序代码中的每个 TemplateLiteral 都与一个唯一的模板对象相关联,该对象用于标记模板的求值(13.2.8.6)。模板对象是冻结的,每次特定标记模板求值时都使用相同的模板对象。模板对象是懒惰创建的(在第一次求值时)还是提前创建的(在第一次求值之前)是实现选择,对 ECMAScript 代码不可见。

注意 3

本规范的未来版本可能会定义模板对象的附加不可枚举属性。

13.2.8.5 运行时语义:SubstitutionEvaluation

SubstitutionEvaluation 是一个 语法导向操作,它不接受参数,并返回一个 正常完成 包含一个 ECMAScript 语言值列表 或一个 异常完成。它在以下产生式上分段定义:

TemplateSpans : TemplateTail
  1. 返回一个新的空 列表
TemplateSpans : TemplateMiddleList TemplateTail
  1. 返回 ? SubstitutionEvaluation of TemplateMiddleList
TemplateMiddleList : TemplateMiddle Expression
  1. subRef 为 ? Evaluation of Expression
  2. sub 为 ? GetValue(subRef)。
  3. 返回 « sub »。
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. preceding 为 ? SubstitutionEvaluation of TemplateMiddleList
  2. nextRef 为 ? Evaluation of Expression
  3. next 为 ? GetValue(nextRef)。
  4. 返回 preceding 和 « next » 的 列表连接

13.2.8.6 运行时语义:求值

TemplateLiteral : NoSubstitutionTemplate
  1. 返回 NoSubstitutionTemplateTV,定义在 12.9.6
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. headTemplateHeadTV,定义在 12.9.6
  2. subRef 为 ? Evaluation of Expression
  3. sub 为 ? GetValue(subRef)。
  4. middle 为 ? ToString(sub)。
  5. tail 为 ? Evaluation of TemplateSpans
  6. 返回 headmiddletail字符串连接
注意 1

Expression 值的字符串转换语义类似于 String.prototype.concat 而不是 + 运算符。

TemplateSpans : TemplateTail
  1. 返回 TemplateTailTV,定义在 12.9.6
TemplateSpans : TemplateMiddleList TemplateTail
  1. head 为 ? Evaluation of TemplateMiddleList
  2. tailTemplateTailTV,定义在 12.9.6
  3. 返回 headtail字符串连接
TemplateMiddleList : TemplateMiddle Expression
  1. headTemplateMiddleTV,定义在 12.9.6
  2. subRef 为 ? Evaluation of Expression
  3. sub 为 ? GetValue(subRef)。
  4. middle 为 ? ToString(sub)。
  5. 返回 headmiddle字符串连接
注意 2

Expression 值的字符串转换语义类似于 String.prototype.concat 而不是 + 运算符。

TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. rest 为 ? Evaluation of TemplateMiddleList
  2. middleTemplateMiddleTV,定义在 12.9.6
  3. subRef 为 ? Evaluation of Expression
  4. sub 为 ? GetValue(subRef)。
  5. last 为 ? ToString(sub)。
  6. 返回 restmiddlelast字符串连接
注意 3

Expression 值的字符串转换语义类似于 String.prototype.concat 而不是 + 运算符。

13.2.9 分组运算符

13.2.9.1 静态语义:早期错误

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList

13.2.9.2 运行时语义:求值

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprParenthesizedExpression覆盖CoverParenthesizedExpressionAndArrowParameterList
  2. 返回 ? Evaluation of expr
ParenthesizedExpression : ( Expression )
  1. 返回 ? Evaluation of Expression。这可能是 Reference 类型。
注意

此算法不会对 Evaluation of Expression 应用 GetValue。这样做的主要动机是允许诸如 deletetypeof 等运算符应用于带括号的表达式。

13.3 左值表达式

语法

MemberExpression[Yield, Await] : PrimaryExpression[?Yield, ?Await] MemberExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] MemberExpression[?Yield, ?Await] . IdentifierName MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] SuperProperty[?Yield, ?Await] MetaProperty new MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] MemberExpression[?Yield, ?Await] . PrivateIdentifier SuperProperty[Yield, Await] : super [ Expression[+In, ?Yield, ?Await] ] super . IdentifierName MetaProperty : NewTarget ImportMeta NewTarget : new . target ImportMeta : import . meta NewExpression[Yield, Await] : MemberExpression[?Yield, ?Await] new NewExpression[?Yield, ?Await] CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] SuperCall[?Yield, ?Await] ImportCall[?Yield, ?Await] CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await] CallExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] CallExpression[?Yield, ?Await] . IdentifierName CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] CallExpression[?Yield, ?Await] . PrivateIdentifier SuperCall[Yield, Await] : super Arguments[?Yield, ?Await] ImportCall[Yield, Await] : import ( AssignmentExpression[+In, ?Yield, ?Await] ) Arguments[Yield, Await] : ( ) ( ArgumentList[?Yield, ?Await] ) ( ArgumentList[?Yield, ?Await] , ) ArgumentList[Yield, Await] : AssignmentExpression[+In, ?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , ... AssignmentExpression[+In, ?Yield, ?Await] OptionalExpression[Yield, Await] : MemberExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalChain[Yield, Await] : ?. Arguments[?Yield, ?Await] ?. [ Expression[+In, ?Yield, ?Await] ] ?. IdentifierName ?. TemplateLiteral[?Yield, ?Await, +Tagged] ?. PrivateIdentifier OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await] OptionalChain[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] OptionalChain[?Yield, ?Await] . IdentifierName OptionalChain[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] OptionalChain[?Yield, ?Await] . PrivateIdentifier LeftHandSideExpression[Yield, Await] : NewExpression[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalExpression[?Yield, ?Await]

补充语法

当处理以下产生式的一个实例时
CallExpression : CoverCallExpressionAndAsyncArrowHead
CoverCallExpressionAndAsyncArrowHead 的解释使用以下语法进行细化:

CallMemberExpression[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

13.3.1 静态语义

13.3.1.1 静态语义:早期错误

OptionalChain : ?. TemplateLiteral OptionalChain TemplateLiteral
  • 如果任何源代码与此产生式匹配,则这是一个语法错误。
注意

此产生式存在是为了防止自动分号插入规则(12.10)应用于以下代码:

a?.b
`c`

以便将其解释为两个有效的语句。目的是保持与没有可选链的类似代码的一致性:

a.b
`c`

这是一个有效的语句,并且自动分号插入不适用。

ImportMeta : import . meta

13.3.2 属性访问器

注意

属性通过名称访问,使用点表示法:

或方括号表示法:

点表示法通过以下句法转换解释:

其行为与以下相同:

MemberExpression [ <identifier-name-string> ]

同样地:

其行为与以下相同:

CallExpression [ <identifier-name-string> ]

其中 <identifier-name-string> 是评估 StringValueIdentifierName 的结果。

13.3.2.1 运行时语义:评估

MemberExpression : MemberExpression [ Expression ]
  1. baseReference 为 ? EvaluationMemberExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. 如果 源代码匹配MemberExpression严格模式代码,设 stricttrue;否则设 strictfalse
  4. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
MemberExpression : MemberExpression . IdentifierName
  1. baseReference 为 ? EvaluationMemberExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. 如果 源代码匹配MemberExpression严格模式代码,设 stricttrue;否则设 strictfalse
  4. 返回 EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
MemberExpression : MemberExpression . PrivateIdentifier
  1. baseReference 为 ? EvaluationMemberExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. fieldNameStringStringValuePrivateIdentifier
  4. 返回 MakePrivateReference(baseValue, fieldNameString)。
CallExpression : CallExpression [ Expression ]
  1. baseReference 为 ? EvaluationCallExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. 如果 源代码匹配CallExpression严格模式代码,设 stricttrue;否则设 strictfalse
  4. 返回 ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
CallExpression : CallExpression . IdentifierName
  1. baseReference 为 ? EvaluationCallExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. 如果 源代码匹配CallExpression严格模式代码,设 stricttrue;否则设 strictfalse
  4. 返回 EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
CallExpression : CallExpression . PrivateIdentifier
  1. baseReference 为 ? EvaluationCallExpression
  2. baseValue 为 ? GetValue(baseReference)。
  3. fieldNameStringStringValuePrivateIdentifier
  4. 返回 MakePrivateReference(baseValue, fieldNameString)。

13.3.3 EvaluatePropertyAccessWithExpressionKey ( baseValue, expression, strict )

抽象操作 EvaluatePropertyAccessWithExpressionKey 接受参数 baseValue(一个 ECMAScript 语言值),expression(一个 Expression 解析节点),和 strict(一个布尔值),并返回一个 正常完成 包含一个 引用记录 或一个 突然完成。它在调用时执行以下步骤:

  1. propertyNameReference 为 ? Evaluationexpression
  2. propertyNameValue 为 ? GetValue(propertyNameReference)。
  3. propertyKey 为 ? ToPropertyKey(propertyNameValue)。
  4. 返回 引用记录 { [[Base]]: baseValue, [[ReferencedName]]: propertyKey, [[Strict]]: strict, [[ThisValue]]: empty }。

13.3.4 EvaluatePropertyAccessWithIdentifierKey ( baseValue, identifierName, strict )

抽象操作 EvaluatePropertyAccessWithIdentifierKey 接受参数 baseValue(一个 ECMAScript 语言值),identifierName(一个 IdentifierName 解析节点),和 strict(一个布尔值),并返回一个 引用记录。它在调用时执行以下步骤:

  1. propertyNameStringStringValueidentifierName
  2. 返回 引用记录 { [[Base]]: baseValue, [[ReferencedName]]: propertyNameString, [[Strict]]: strict, [[ThisValue]]: empty }。

13.3.5 The new Operator

13.3.5.1 运行时语义:评估

NewExpression : new NewExpression
  1. 返回 ? EvaluateNew(NewExpression, empty)。
MemberExpression : new MemberExpression Arguments
  1. 返回 ? EvaluateNew(MemberExpression, Arguments)。

13.3.5.1.1 EvaluateNew ( constructExpr, arguments )

抽象操作 EvaluateNew 接受参数 constructExpr(一个 NewExpression 解析节点 或一个 MemberExpression 解析节点)和 argumentsempty 或一个 Arguments 解析节点),并返回 一个 正常完成 包含一个 ECMAScript 语言值 或一个 突然完成。它在调用时执行以下步骤:

  1. ref 为 ? EvaluationconstructExpr
  2. constructor 为 ? GetValue(ref)。
  3. 如果 argumentsempty
    1. argList 为一个新空的 列表
  4. 否则,
    1. argList 为 ? ArgumentListEvaluationarguments
  5. 如果 IsConstructor(constructor) is false,抛出一个 TypeError 异常。
  6. 返回 ? Construct(constructor, argList)。

13.3.6 Function Calls

13.3.6.1 运行时语义:评估

CallExpression : CoverCallExpressionAndAsyncArrowHead
  1. exprCallMemberExpressionCoverCallExpressionAndAsyncArrowHead 覆盖的部分。
  2. memberExprexprMemberExpression
  3. argumentsexprArguments
  4. ref 为 ? EvaluationmemberExpr
  5. func 为 ? GetValue(ref)。
  6. 如果 ref 是一个 引用记录IsPropertyReference(ref) 是 false,且 ref.[[ReferencedName]]"eval",则
    1. 如果 SameValue(func, %eval%) 是 true,则
      1. argList 为 ? ArgumentListEvaluationarguments
      2. 如果 argList 没有元素,返回 undefined
      3. evalArgargList 的第一个元素。
      4. 如果 源代码匹配CallExpression严格模式代码,设 strictCallertrue。否则设 strictCallerfalse
      5. 返回 ? PerformEval(evalArg, strictCaller, true)。
  7. thisCall 为这个 CallExpression
  8. tailCallIsInTailPosition(thisCall)。
  9. 返回 ? EvaluateCall(func, ref, arguments, tailCall)。

一个 CallExpression 评估执行步骤 6.a.v 是一个 直接 eval

CallExpression : CallExpression Arguments
  1. ref 为 ? EvaluationCallExpression
  2. func 为 ? GetValue(ref)。
  3. thisCall 为这个 CallExpression
  4. tailCallIsInTailPosition(thisCall)。
  5. 返回 ? EvaluateCall(func, ref, Arguments, tailCall)。

13.3.6.2 EvaluateCall ( func, ref, arguments, tailPosition )

抽象操作 EvaluateCall 接受参数 func(一个 ECMAScript 语言值),ref(一个 ECMAScript 语言值 或一个 引用记录),arguments(一个 解析节点), tailPosition(一个布尔值),并返回一个 正常完成 包含一个 ECMAScript 语言值 或一个 突然完成。它在调用时执行以下步骤:

  1. 如果 ref 是一个 引用记录,则
    1. 如果 IsPropertyReference(ref) 是 true,则
      1. thisValueGetThisValue(ref)。
    2. 否则,
      1. refEnvref.[[Base]]
      2. 断言refEnv 是一个 环境记录
      3. thisValuerefEnv.WithBaseObject()。
  2. 否则,
    1. thisValueundefined
  3. argList 为 ? ArgumentListEvaluationarguments
  4. 如果 func 不是一个对象,抛出一个 TypeError 异常。
  5. 如果 IsCallable(func) 是 false,抛出一个 TypeError 异常。
  6. 如果 tailPositiontrue, 执行 PrepareForTailCall()。
  7. 返回 ? Call(func, thisValue, argList)。

13.3.7 The super 关键字

13.3.7.1 运行时语义:评估

SuperProperty : super [ Expression ]
  1. env 为运行时执行上下文的 环境记录
  2. homeenv.GetSuperBase()。
  3. propertyNameReference 为 ? Evaluation表达式
  4. propertyNameValue 为 ? GetValue(propertyNameReference)。
  5. propertyKey 为 ? ToPropertyKey(propertyNameValue)。
  6. strictIsStrictReference(propertyNameReference)。
  7. 返回 MakeSuperPropertyReference(home, propertyKey, strict)。
SuperProperty : super . IdentifierName
  1. env 为运行时执行上下文的 环境记录
  2. homeenv.GetSuperBase()。
  3. strictIsStrictReference(propertyNameReference)。
  4. propertyKeyStringValueIdentifierName
  5. 返回 MakeSuperPropertyReference(home, propertyKey, strict)。
SuperCall : super Arguments
  1. newTargetGetNewTarget()。
  2. 断言newTarget 是一个对象
  3. funcGetSuperConstructor()。
  4. argList 为 ? ArgumentListEvaluationArguments
  5. 如果 IsConstructor(func) 是 false,抛出一个 TypeError 异常。
  6. result 为 ? Construct(func, argList, newTarget)。
  7. thisERGetThisEnvironment()。
  8. 执行 ? thisER.BindThisValue(result)。
  9. FthisER.[[FunctionObject]]
  10. 断言F 是一个 ECMAScript 函数对象
  11. 执行 ? InitializeInstanceElements(result, F)。
  12. 返回 result

13.3.7.2 GetSuperConstructor ( )

抽象操作 GetSuperConstructor 不接受任何参数,并返回一个 ECMAScript 语言值。它在调用时执行以下步骤:

  1. envRecGetThisEnvironment()。
  2. 断言envRec 是一个 函数环境记录
  3. activeFunctionenvRec.[[FunctionObject]]
  4. 断言activeFunction 是一个 ECMAScript 函数对象
  5. superConstructor 为 ! activeFunction.[[GetPrototypeOf]]()。
  6. 返回 superConstructor

13.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict )

抽象操作 MakeSuperPropertyReference 接受参数 actualThis(一个 ECMAScript 语言值),propertyKey(一个 属性键),和 strict(一个布尔值),并返回一个 正常完成 包含一个 Super 引用记录 或一个 抛出完成。它在调用时执行以下步骤:

  1. envGetThisEnvironment()。
  2. 断言env.HasSuperBinding() 是 true
  3. baseValue 为 ? env.GetSuperBase()。
  4. 返回 引用记录 { [[Base]]: baseValue, [[ReferencedName]]: propertyKey, [[Strict]]: strict, [[ThisValue]]: actualThis }。

13.3.8 参数列表

参数列表的评估产生一个列表的 值。

13.3.8.1 运行时语义:参数列表评估

语法导向操作参数列表评估不接受参数,并返回一个正常完成包含一个列表ECMAScript语言值或一个突然完成。它在以下产生式上分段定义:

Arguments : ( )
  1. 返回一个新的空列表
ArgumentList : AssignmentExpression
  1. ref为? AssignmentExpression的评估。
  2. arg为? GetValue(ref)。
  3. 返回 « arg »。
ArgumentList : ... AssignmentExpression
  1. list为一个新空列表
  2. spreadRef为? AssignmentExpression的评估。
  3. spreadObj为? GetValue(spreadRef)。
  4. iteratorRecord为? GetIterator(spreadObj, sync)。
  5. 重复,
    1. next为? IteratorStepValue(iteratorRecord)。
    2. 如果nextdone,返回 list
    3. next添加到list
ArgumentList : ArgumentList , AssignmentExpression
  1. precedingArgs为? ArgumentListEvaluation of ArgumentList
  2. ref为? Evaluation of AssignmentExpression
  3. arg为? GetValue(ref)。
  4. 返回列表连接 of precedingArgs 和 « arg »。
ArgumentList : ArgumentList , ... AssignmentExpression
  1. precedingArgs为? ArgumentListEvaluation of ArgumentList
  2. spreadRef为? Evaluation of AssignmentExpression
  3. iteratorRecord为? GetIterator(? GetValue(spreadRef), sync)。
  4. 重复,
    1. next为? IteratorStepValue(iteratorRecord)。
    2. 如果nextdone,返回 precedingArgs
    3. next添加到precedingArgs
TemplateLiteral : NoSubstitutionTemplate
  1. templateLiteral为这个TemplateLiteral
  2. siteObjGetTemplateObject(templateLiteral)。
  3. 返回 « siteObj »。
TemplateLiteral : SubstitutionTemplate
  1. templateLiteral为这个TemplateLiteral
  2. siteObjGetTemplateObject(templateLiteral)。
  3. remaining为? ArgumentListEvaluation of SubstitutionTemplate
  4. 返回列表连接 of « siteObj » 和 remaining
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. firstSubRef为? Evaluation of Expression
  2. firstSub为? GetValue(firstSubRef)。
  3. restSub为? SubstitutionEvaluation of TemplateSpans
  4. 断言: restSub 是一个 可能为空的列表
  5. 返回列表连接 of « firstSub » 和 restSub

13.3.9 可选链

一个可选链是一个或多个属性访问和函数调用的链,第一个以?.标记开始。

13.3.9.1 运行时语义:评估

OptionalExpression : MemberExpression OptionalChain
  1. baseReference为? Evaluation of MemberExpression
  2. baseValue为? GetValue(baseReference)。
  3. 如果baseValueundefinednull,则
    1. 返回undefined
  4. 返回? ChainEvaluation of OptionalChain with arguments baseValuebaseReference
OptionalExpression : CallExpression OptionalChain
  1. baseReference为? Evaluation of CallExpression
  2. baseValue为? GetValue(baseReference)。
  3. 如果baseValueundefinednull,则
    1. 返回undefined
  4. 返回? ChainEvaluation of OptionalChain with arguments baseValuebaseReference
OptionalExpression : OptionalExpression OptionalChain
  1. baseReference为? Evaluation of OptionalExpression
  2. baseValue为? GetValue(baseReference)。
  3. 如果baseValueundefinednull,则
    1. 返回undefined
  4. 返回? ChainEvaluation of OptionalChain with arguments baseValuebaseReference

13.3.9.2 运行时语义:链评估

语法导向操作链评估接受参数baseValue(一个ECMAScript语言值)和baseReference(一个ECMAScript语言值或一个引用记录),并返回一个正常完成,包含一个ECMAScript语言值或一个引用记录,或一个突然完成。它在以下产生式上分段定义:

OptionalChain : ?. Arguments
  1. thisChain为这个OptionalChain
  2. tailCallIsInTailPosition(thisChain)。
  3. 返回? EvaluateCall(baseValue, baseReference, Arguments, tailCall)。
OptionalChain : ?. [ Expression ]
  1. 如果这个OptionalChain源文本匹配严格模式代码,设stricttrue;否则设strictfalse
  2. 返回? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)。
OptionalChain : ?. IdentifierName
  1. 如果这个OptionalChain源文本匹配严格模式代码,设stricttrue;否则设strictfalse
  2. 返回EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)。
OptionalChain : ?. PrivateIdentifier
  1. fieldNameStringPrivateIdentifierStringValue
  2. 返回MakePrivateReference(baseValue, fieldNameString)。
OptionalChain : OptionalChain Arguments
  1. optionalChainOptionalChain
  2. newReference为? ChainEvaluation of optionalChain with arguments baseValuebaseReference
  3. newValue为? GetValue(newReference)。
  4. thisChain为这个OptionalChain
  5. tailCallIsInTailPosition(thisChain)。
  6. 返回? EvaluateCall(newValue, newReference, Arguments, tailCall)。
OptionalChain : OptionalChain [ Expression ]
  1. optionalChainOptionalChain
  2. newReference为? ChainEvaluation of optionalChain with arguments baseValuebaseReference
  3. newValue为? GetValue(newReference)。
  4. 如果这个OptionalChain源文本匹配严格模式代码,设stricttrue;否则设strictfalse
  5. 返回? EvaluatePropertyAccessWithExpressionKey(newValue, Expression, strict)。
OptionalChain : OptionalChain . IdentifierName
  1. optionalChainOptionalChain
  2. newReference为? ChainEvaluation of optionalChain with arguments baseValuebaseReference
  3. newValue为? GetValue(newReference)。
  4. 如果这个OptionalChain源文本匹配严格模式代码,设stricttrue;否则设strictfalse
  5. 返回EvaluatePropertyAccessWithIdentifierKey(newValue, IdentifierName, strict)。
OptionalChain : OptionalChain . PrivateIdentifier
  1. optionalChainOptionalChain
  2. newReference为? ChainEvaluation of optionalChain with arguments baseValuebaseReference
  3. newValue为? GetValue(newReference)。
  4. fieldNameStringPrivateIdentifierStringValue
  5. 返回MakePrivateReference(newValue, fieldNameString)。

13.3.10 Import 调用

13.3.10.1 运行时语义: Evaluation

ImportCall : import ( AssignmentExpression )
  1. referrerGetActiveScriptOrModule()。
  2. 如果referrernull,设 referrer当前领域记录
  3. argRef为? Evaluation of AssignmentExpression
  4. specifier为? GetValue(argRef)。
  5. promiseCapability为! NewPromiseCapability(%Promise%)。
  6. specifierStringCompletion(ToString(specifier))。
  7. IfAbruptRejectPromise(specifierString, promiseCapability)。
  8. 执行HostLoadImportedModule(referrer, specifierString, empty, promiseCapability)。
  9. 返回promiseCapability.[[Promise]]

13.3.10.1.1 ContinueDynamicImport ( promiseCapability, moduleCompletion )

抽象操作ContinueDynamicImport接受参数promiseCapability(一个PromiseCapability Record)和moduleCompletion(一个正常完成包含一个Module Record或一个抛出完成)并返回unused。它完成了一个动态导入的原始过程,最初由一个import()调用启动,根据需要解决或拒绝该调用返回的承诺。它执行以下步骤:

  1. 如果moduleCompletion是一个突然完成,则
    1. 执行! Call(promiseCapability.[[Reject]], undefined, « moduleCompletion.[[Value]] »)。
    2. 返回unused
  2. modulemoduleCompletion.[[Value]]
  3. loadPromisemodule.LoadRequestedModules()。
  4. rejectedClosure为一个新抽象闭包,参数为(reason),捕获promiseCapability,并执行以下步骤:
    1. 执行! Call(promiseCapability.[[Reject]], undefined, « reason »)。
    2. 返回unused
  5. onRejectedCreateBuiltinFunction(rejectedClosure, 1, "", « »)。
  6. linkAndEvaluateClosure为一个新抽象闭包,无参数,捕获modulepromiseCapabilityonRejected,并执行以下步骤:
    1. linkCompletion(module.Link())。
    2. 如果link是一个突然完成,则
      1. 执行! Call(promiseCapability.[[Reject]], undefined, « link.[[Value]] »)。
      2. 返回unused
    3. evaluatePromisemodule.Evaluate()。
    4. fulfilledClosure为一个新抽象闭包 ,无参数,捕获modulepromiseCapability,并执行以下步骤:
      1. namespaceGetModuleNamespace(module)。
      2. 执行! Call(promiseCapability.[[Resolve]], undefined, « namespace »)。
      3. 返回unused
    5. onFulfilledCreateBuiltinFunction(fulfilledClosure, 0, "", « »)。
    6. 执行PerformPromiseThen(evaluatePromise, onFulfilled, onRejected)。
    7. 返回unused
  7. linkAndEvaluateCreateBuiltinFunction(linkAndEvaluateClosure, 0, "", « »)。
  8. 执行PerformPromiseThen(loadPromise, linkAndEvaluate, onRejected)。
  9. 返回unused

13.3.11 标签模板

标签模板是一个函数调用,其中调用的参数是从一个TemplateLiteral (13.2.8) 派生的。实际参数包括一个模板对象 (13.2.8.4) 和通过评估嵌入在TemplateLiteral中的表达式产生的值。

13.3.11.1 运行时语义:评估

MemberExpression : MemberExpression TemplateLiteral
  1. tagRef为? Evaluation of MemberExpression
  2. tagFunc为? GetValue(tagRef)。
  3. thisCall为这个MemberExpression
  4. tailCallIsInTailPosition(thisCall)。
  5. 返回? EvaluateCall(tagFunc, tagRef, TemplateLiteral, tailCall)。
CallExpression : CallExpression TemplateLiteral
  1. tagRef为? Evaluation of CallExpression
  2. tagFunc为? GetValue(tagRef)。
  3. thisCall为这个CallExpression
  4. tailCallIsInTailPosition(thisCall)。
  5. 返回? EvaluateCall(tagFunc, tagRef, TemplateLiteral, tailCall)。

13.3.12 元属性

13.3.12.1 运行时语义: Evaluation

NewTarget : new . target
  1. 返回 GetNewTarget()。
ImportMeta : import . meta
  1. moduleGetActiveScriptOrModule()。
  2. 断言module 是一个 源文本模块记录
  3. importMetamodule.[[ImportMeta]]
  4. 如果 importMetaempty, 则
    1. importMetaOrdinaryObjectCreate(null)。
    2. importMetaValuesHostGetImportMetaProperties(module)。
    3. 对于每个 记录 { [[Key]], [[Value]] } pimportMetaValues,执行
      1. 执行 ! CreateDataPropertyOrThrow(importMeta, p.[[Key]], p.[[Value]])。
    4. 执行 HostFinalizeImportMeta(importMeta, module)。
    5. module.[[ImportMeta]]importMeta
    6. 返回 importMeta
  5. 否则,
    1. 断言importMeta 是一个对象
    2. 返回 importMeta

13.3.12.1.1 HostGetImportMetaProperties ( moduleRecord )

The 宿主定义 抽象操作 HostGetImportMetaProperties 接受参数 moduleRecord(一个 模块记录)并 返回一个 列表记录 带有字段 [[Key]](一个 属性键)和 [[Value]](一个 ECMAScript 语言 值)。它允许 宿主 提供 属性 键 和值给从 import.meta 返回的对象。

HostGetImportMetaProperties 的默认实现是返回一个新的空 列表

13.3.12.1.2 HostFinalizeImportMeta ( importMeta, moduleRecord )

The 宿主定义 抽象操作 HostFinalizeImportMeta 接受参数 importMeta(一个对象)和 moduleRecord (一个 模块记录)并 返回 unused。它允许 宿主 执行任何非凡的操作来准备从 import.meta 返回的对象。

大多数 宿主 可以简单地定义 HostGetImportMetaProperties, 并让 HostFinalizeImportMeta 保持其默认行为。然而,HostFinalizeImportMeta 为 宿主 提供了一个“逃生舱”,可以在对象暴露给 ECMAScript 代码之前直接操作它。

HostFinalizeImportMeta 的默认实现是返回 unused

13.4 更新表达式

语法

UpdateExpression[Yield, Await] : LeftHandSideExpression[?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] ++ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] -- ++ UnaryExpression[?Yield, ?Await] -- UnaryExpression[?Yield, ?Await]

13.4.1 静态语义:早期错误

UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- UpdateExpression : ++ UnaryExpression -- UnaryExpression

13.4.2 后置递增运算符

13.4.2.1 运行时语义:评估

UpdateExpression : LeftHandSideExpression ++
  1. lhs 为 ? 评估LeftHandSideExpression
  2. oldValue 为 ? ToNumeric(? GetValue(lhs))。
  3. 如果 oldValue 是一个 数字,则
    1. newValueNumber::add(oldValue, 1𝔽)。
  4. 否则,
    1. 断言oldValue 是一个 大整数
    2. newValueBigInt::add(oldValue, 1)。
  5. 执行 ? PutValue(lhs, newValue)。
  6. 返回 oldValue

13.4.3 后置递减运算符

13.4.3.1 运行时语义:评估

UpdateExpression : LeftHandSideExpression --
  1. lhs 为 ? 评估LeftHandSideExpression
  2. oldValue 为 ? ToNumeric(? GetValue(lhs))。
  3. 如果 oldValue 是一个 数字,则
    1. newValueNumber::subtract(oldValue, 1𝔽)。
  4. 否则,
    1. 断言oldValue 是一个 大整数
    2. newValueBigInt::subtract(oldValue, 1)。
  5. 执行 ? PutValue(lhs, newValue)。
  6. 返回 oldValue

13.4.4 前置递增运算符

13.4.4.1 运行时语义:评估

UpdateExpression : ++ UnaryExpression
  1. expr 为 ? 评估UnaryExpression
  2. oldValue 为 ? ToNumeric(? GetValue(expr))。
  3. 如果 oldValue 是一个 数字,则
    1. newValueNumber::add(oldValue, 1𝔽)。
  4. 否则,
    1. 断言oldValue 是一个 大整数
    2. newValueBigInt::add(oldValue, 1)。
  5. 执行 ? PutValue(expr, newValue)。
  6. 返回 newValue

13.4.5 前置递减运算符

13.4.5.1 运行时语义:评估

UpdateExpression : -- UnaryExpression
  1. expr 为 ? 评估UnaryExpression
  2. oldValue 为 ? ToNumeric(? GetValue(expr))。
  3. 如果 oldValue 是一个 数字,则
    1. newValueNumber::subtract(oldValue, 1𝔽)。
  4. 否则,
    1. 断言oldValue 是一个 大整数
    2. newValueBigInt::subtract(oldValue, 1)。
  5. 执行 ? PutValue(expr, newValue)。
  6. 返回 newValue

13.5 一元运算符

语法

UnaryExpression[Yield, Await] : UpdateExpression[?Yield, ?Await] delete UnaryExpression[?Yield, ?Await] void UnaryExpression[?Yield, ?Await] typeof UnaryExpression[?Yield, ?Await] + UnaryExpression[?Yield, ?Await] - UnaryExpression[?Yield, ?Await] ~ UnaryExpression[?Yield, ?Await] ! UnaryExpression[?Yield, ?Await] [+Await] AwaitExpression[?Yield]

13.5.1 The delete 运算符

13.5.1.1 静态语义:早期错误

UnaryExpression : delete UnaryExpression 注意

最后一项规则意味着表达式如 delete (((foo))) 会产生 早期错误,因为递归应用了第一项规则。

13.5.1.2 运行时语义:评估

UnaryExpression : delete UnaryExpression
  1. ref 为 ? 评估UnaryExpression
  2. 如果 ref 不是 引用记录,返回 true
  3. 如果 IsUnresolvableReference(ref) 是 true,则
    1. 断言ref.[[Strict]]false
    2. 返回 true
  4. 如果 IsPropertyReference(ref) 是 true,则
    1. 断言IsPrivateReference(ref) 是 false
    2. 如果 IsSuperReference(ref) 是 true,抛出 ReferenceError 异常。
    3. baseObj 为 ? ToObject(ref.[[Base]])。
    4. deleteStatus 为 ? baseObj.[[Delete]](ref.[[ReferencedName]])。
    5. 如果 deleteStatusfalse 并且 ref.[[Strict]]true,抛出 TypeError 异常。
    6. 返回 deleteStatus
  5. 否则,
    1. baseref.[[Base]]
    2. 断言base环境记录
    3. 返回 ? base.DeleteBinding(ref.[[ReferencedName]])。
注意 1

delete 运算符出现在 严格模式代码 中时,如果其 UnaryExpression 是直接引用变量、函数参数或函数名,则抛出 SyntaxError 异常。此外,如果 delete 运算符出现在 严格模式代码 中,并且要删除的属性具有属性 { [[Configurable]]: false }(或无法删除),则抛出 TypeError 异常。

注意 2

在步骤 4.c 中可能创建的对象在上述抽象操作和 普通对象[[Delete]] 内部方法之外不可访问。实现可能会选择避免实际创建该对象。

13.5.2 The void 运算符

13.5.2.1 运行时语义:评估

UnaryExpression : void UnaryExpression
  1. expr 为 ? 评估UnaryExpression
  2. 执行 ? GetValue(expr)。
  3. 返回 undefined
注意

GetValue 必须被调用,即使它的值没有被使用,因为它可能有可观察的副作用。

13.5.3 The typeof 运算符

13.5.3.1 运行时语义:评估

UnaryExpression : typeof UnaryExpression
  1. val 为 ? 评估UnaryExpression
  2. 如果 val引用记录,则
    1. 如果 IsUnresolvableReference(val) 是 true,返回 "undefined"
  3. val 为 ? GetValue(val)。
  4. 如果 valundefined,返回 "undefined"
  5. 如果 valnull,返回 "object"
  6. 如果 val 是字符串,返回 "string"
  7. 如果 val 是符号,返回 "symbol"
  8. 如果 val 是布尔值,返回 "boolean"
  9. 如果 val 是数字,返回 "number"
  10. 如果 val 是大整数,返回 "bigint"
  11. 断言val 是对象
  12. 注意:这一步在章节 B.3.6.3 中被替换。
  13. 如果 val[[Call]] 内部槽,返回 "function"
  14. 返回 "object"

13.5.4 一元 + 运算符

注意

一元 + 运算符将其操作数转换为 数字类型

13.5.4.1 运行时语义:评估

UnaryExpression : + UnaryExpression
  1. expr 为 ? 评估UnaryExpression
  2. 返回 ? ToNumber(? GetValue(expr))。

13.5.5 一元 - 运算符

注意

一元 - 运算符将其操作数转换为数值,然后对其取反。取反 +0𝔽 产生 -0𝔽,取反 -0𝔽 产生 +0𝔽

13.5.5.1 运行时语义:评估

UnaryExpression : - UnaryExpression
  1. expr 为 ? 评估UnaryExpression
  2. oldValue 为 ? ToNumeric(? GetValue(expr))。
  3. 如果 oldValue 是数字,则
    1. 返回 Number::unaryMinus(oldValue)。
  4. 否则,
    1. 断言oldValue 是大整数
    2. 返回 BigInt::unaryMinus(oldValue)。

13.5.6 按位 NOT 运算符 ( ~ )

13.5.6.1 运行时语义:评估

UnaryExpression : ~ UnaryExpression
  1. expr 为 ? 评估UnaryExpression
  2. oldValue 为 ? ToNumeric(? GetValue(expr))。
  3. 如果 oldValue 是数字,则
    1. 返回 Number::bitwiseNOT(oldValue)。
  4. 否则,
    1. 断言oldValue 是大整数
    2. 返回 BigInt::bitwiseNOT(oldValue)。

13.5.7 逻辑 NOT 运算符 ( ! )

13.5.7.1 运行时语义:评估

UnaryExpression : ! UnaryExpression
  1. expr 为 ? 评估UnaryExpression
  2. oldValueToBoolean(? GetValue(expr))。
  3. 如果 oldValuetrue,返回 false
  4. 返回 true

13.6 幂运算符

语法

ExponentiationExpression[Yield, Await] : UnaryExpression[?Yield, ?Await] UpdateExpression[?Yield, ?Await] ** ExponentiationExpression[?Yield, ?Await]

13.6.1 运行时语义:评估

ExponentiationExpression : UpdateExpression ** ExponentiationExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(UpdateExpression, **, ExponentiationExpression).

13.7 乘法运算符

语法

MultiplicativeExpression[Yield, Await] : ExponentiationExpression[?Yield, ?Await] MultiplicativeExpression[?Yield, ?Await] MultiplicativeOperator ExponentiationExpression[?Yield, ?Await] MultiplicativeOperator : one of * / % 注意
  • 运算符 * 执行乘法,生成其操作数的乘积。
  • 运算符 / 执行除法,生成其操作数的商。
  • 运算符 % 生成其操作数在隐式除法中的余数。

13.7.1 运行时语义:评估

MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression
  1. opText源文本匹配的 MultiplicativeOperator
  2. 返回 ? EvaluateStringOrNumericBinaryExpression(MultiplicativeExpression, opText, ExponentiationExpression)。

13.8 加法运算符

语法

AdditiveExpression[Yield, Await] : MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] + MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] - MultiplicativeExpression[?Yield, ?Await]

13.8.1 加法运算符 ( + )

注意

加法运算符既可以执行字符串连接,也可以执行数值加法。

13.8.1.1 运行时语义:评估

AdditiveExpression : AdditiveExpression + MultiplicativeExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(AdditiveExpression, +, MultiplicativeExpression)。

13.8.2 减法运算符 ( - )

注意

减法运算符执行减法,生成其操作数的差值。

13.8.2.1 运行时语义:评估

AdditiveExpression : AdditiveExpression - MultiplicativeExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(AdditiveExpression, -, MultiplicativeExpression)。

13.9 位移运算符

语法

ShiftExpression[Yield, Await] : AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] << AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >> AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >>> AdditiveExpression[?Yield, ?Await]

13.9.1 左移运算符 ( << )

注意

对左操作数执行按位左移操作,移动的位数由右操作数指定。

13.9.1.1 运行时语义:评估

ShiftExpression : ShiftExpression << AdditiveExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(ShiftExpression, <<, AdditiveExpression)。

13.9.2 带符号右移运算符 ( >> )

注意

对左操作数执行按位右移操作,移动的位数由右操作数指定,并使用符号位填充空出的位。

13.9.2.1 运行时语义:评估

ShiftExpression : ShiftExpression >> AdditiveExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(ShiftExpression, >>, AdditiveExpression)。

13.9.3 无符号右移运算符 ( >>> )

注意

对左操作数执行按位右移操作,移动的位数由右操作数指定,并使用零填充空出的位。

13.9.3.1 运行时语义:评估

ShiftExpression : ShiftExpression >>> AdditiveExpression
  1. 返回 ? EvaluateStringOrNumericBinaryExpression(ShiftExpression, >>>, AdditiveExpression)。

13.10 关系运算符

注释 1

关系运算符的求值结果总是布尔类型,反映运算符命名的关系是否在其两个操作数之间成立。

语法

RelationalExpression [In, Yield, Await] : ShiftExpression [?Yield, ?Await] RelationalExpression [?In, ?Yield, ?Await] < ShiftExpression [?Yield, ?Await] RelationalExpression [?In, ?Yield, ?Await] > ShiftExpression [?Yield, ?Await] RelationalExpression [?In, ?Yield, ?Await] <= ShiftExpression [?Yield, ?Await] RelationalExpression [?In, ?Yield, ?Await] >= ShiftExpression [?Yield, ?Await] RelationalExpression [?In, ?Yield, ?Await] instanceof ShiftExpression [?Yield, ?Await] [+In] RelationalExpression [+In, ?Yield, ?Await] in ShiftExpression [?Yield, ?Await] [+In] PrivateIdentifier in ShiftExpression [?Yield, ?Await] 注释 2

[In] 语法参数是为了避免在关系表达式中混淆 in 运算符和 for 语句中的 in 运算符。

13.10.1 运行时语义: 求值

RelationalExpression : RelationalExpression < ShiftExpression
  1. lref 为 ?  Evaluation of RelationalExpression
  2. lval 为 ?  GetValue (lref)。
  3. rref 为 ?  Evaluation of ShiftExpression
  4. rval 为 ?  GetValue (rref)。
  5. r 为 ?  IsLessThan (lval, rval, true)。
  6. 如果 rundefined,返回 false。否则,返回 r
RelationalExpression : RelationalExpression > ShiftExpression
  1. lref 为 ?  Evaluation of RelationalExpression
  2. lval 为 ?  GetValue (lref)。
  3. rref 为 ?  Evaluation of ShiftExpression
  4. rval 为 ?  GetValue (rref)。
  5. r 为 ?  IsLessThan (rval, lval, false)。
  6. 如果 rundefined,返回 false。否则,返回 r
RelationalExpression : RelationalExpression <= ShiftExpression
  1. lref 为 ?  Evaluation of RelationalExpression
  2. lval 为 ?  GetValue (lref)。
  3. rref 为 ?  Evaluation of ShiftExpression
  4. rval 为 ?  GetValue (rref)。
  5. r 为 ?  IsLessThan (rval, lval, false)。
  6. 如果 rtrueundefined,返回 false。否则,返回 true
RelationalExpression : RelationalExpression >= ShiftExpression
  1. lref 为 ?  Evaluation of RelationalExpression
  2. lval 为 ?  GetValue (lref)。
  3. rref 为 ?  Evaluation of ShiftExpression
  4. rval 为 ?  GetValue (rref)。
  5. r 为 ?  IsLessThan (lval, rval, true)。
  6. 如果 rtrueundefined,返回 false。否则,返回 true
RelationalExpression : RelationalExpression instanceof ShiftExpression
  1. lref 为 ?  Evaluation of RelationalExpression
  2. lval 为 ?  GetValue (lref)。
  3. rref 为 ?  Evaluation of ShiftExpression
  4. rval 为 ?  GetValue (rref)。
  5. 返回 ?  InstanceofOperator (lval, rval)。
RelationalExpression : RelationalExpression in ShiftExpression
  1. lref 为 ?  Evaluation of RelationalExpression
  2. lval 为 ?  GetValue (lref)。
  3. rref 为 ?  Evaluation of ShiftExpression
  4. rval 为 ?  GetValue (rref)。
  5. 如果 rval 不是对象 ,抛出 TypeError 异常。
  6. 返回 ?  HasProperty (rval,?  ToPropertyKey (lval))。
RelationalExpression : PrivateIdentifier in ShiftExpression
  1. privateIdentifier StringValue of PrivateIdentifier
  2. rref 为 ?  Evaluation of ShiftExpression
  3. rval 为 ?  GetValue (rref)。
  4. 如果 rval 不是对象 ,抛出 TypeError 异常。
  5. privateEnv 运行执行上下文 的 PrivateEnvironment。
  6. privateName ResolvePrivateIdentifier (privateEnvprivateIdentifier)。
  7. 如果 PrivateElementFind (rvalprivateName) 不是 empty,返回 true
  8. 返回 false

13.10.2 InstanceofOperator ( V, target )

抽象操作 InstanceofOperator 接受参数 V(一个 ECMAScript 语言值 )和 target(一个 ECMAScript 语言值 )并返回一个包含布尔值或抛出完成记录的 正常完成 记录。它实现了一个通用算法,用于确定 V 是否是 target 的实例,方法是咨询 target @@hasInstance 方法,或者在没有这种方法的情况下,确定 target"prototype" 属性的值是否存在于 V 的原型链中。调用时执行以下步骤:

  1. 如果 target 不是对象 ,抛出 TypeError 异常。
  2. instOfHandler 为 ?  GetMethod (target @@hasInstance )。
  3. 如果 instOfHandler 不是 undefined,则
    1. 返回 ToBoolean (? Call (instOfHandlertarget,« V »))。
  4. 如果 IsCallable (target) 是 false,抛出 TypeError 异常。
  5. 返回 ?  OrdinaryHasInstance (targetV)。
注释

步骤 4 5 提供了与以前版本的 ECMAScript 的兼容性,这些版本没有使用 @@hasInstance 方法来定义 instanceof 运算符语义。如果对象没有定义或继承 @@hasInstance ,它将使用默认的 instanceof 语义。

13.11 等值运算符

注释

等值运算符的求值结果总是布尔类型,反映运算符命名的关系是否在其两个操作数之间成立。

语法

EqualityExpression [In, Yield, Await] : RelationalExpression [?In, ?Yield, ?Await] EqualityExpression [?In, ?Yield, ?Await] == RelationalExpression [?In, ?Yield, ?Await] EqualityExpression [?In, ?Yield, ?Await] != RelationalExpression [?In, ?Yield, ?Await] EqualityExpression [?In, ?Yield, ?Await] === RelationalExpression [?In, ?Yield, ?Await] EqualityExpression [?In, ?Yield, ?Await] !== RelationalExpression [?In, ?Yield, ?Await]

13.11.1 运行时语义:求值

EqualityExpression : EqualityExpression == RelationalExpression
  1. lref 为 ?  Evaluation of EqualityExpression
  2. lval 为 ?  GetValue (lref)。
  3. rref 为 ?  Evaluation of RelationalExpression
  4. rval 为 ?  GetValue (rref)。
  5. 返回 ?  IsLooselyEqual (rval, lval)。
EqualityExpression : EqualityExpression != RelationalExpression
  1. lref 为 ?  Evaluation of EqualityExpression
  2. lval 为 ?  GetValue (lref)。
  3. rref 为 ?  Evaluation of RelationalExpression
  4. rval 为 ?  GetValue (rref)。
  5. r 为 ?  IsLooselyEqual (rval, lval)。
  6. 如果 rtrue,返回 false。否则,返回 true
EqualityExpression : EqualityExpression === RelationalExpression
  1. lref 为 ?  Evaluation of EqualityExpression
  2. lval 为 ?  GetValue (lref)。
  3. rref 为 ?  Evaluation of RelationalExpression
  4. rval 为 ?  GetValue (rref)。
  5. 返回 IsStrictlyEqual (rval, lval)。
EqualityExpression : EqualityExpression !== RelationalExpression
  1. lref 为 ?  Evaluation of EqualityExpression
  2. lval 为 ?  GetValue (lref)。
  3. rref 为 ?  Evaluation of RelationalExpression
  4. rval 为 ?  GetValue (rref)。
  5. r IsStrictlyEqual (rval, lval)。
  6. 如果 rtrue,返回 false。否则,返回 true
注释 1

根据上述等值定义:

  • 字符串比较可以通过:`${a}` == `${b}` 强制进行。
  • 数字比较可以通过:+a == +b 强制进行。
  • 布尔值比较可以通过:!a == !b 强制进行。
注释 2

等值运算符保持以下不变量:

  • A != B 等价于 !(A == B)
  • A == B 等价于 B == A,除了 AB 的求值顺序。
注释 3

等值运算符并不总是传递的。例如,可能存在两个不同的字符串对象,每个对象表示相同的字符串值;每个字符串对象会被 == 运算符视为与字符串值相等,但这两个字符串对象彼此并不相等。例如:

  • new String("a") == "a""a" == new String("a") 均为 true
  • new String("a") == new String("a")false
注释 4

字符串比较使用简单的代码单元值相等测试。不会尝试使用 Unicode 规范中定义的更复杂的、语义导向的字符或字符串相等性定义和排序顺序。因此,根据 Unicode 标准规范等价的字符串值可能会被测试为不相等。实际上,这个算法假设两个字符串都已处于规范化形式。

13.12 二进制按位运算符

语法

BitwiseANDExpression [In, Yield, Await] : EqualityExpression [?In, ?Yield, ?Await] BitwiseANDExpression [?In, ?Yield, ?Await] & EqualityExpression [?In, ?Yield, ?Await] BitwiseXORExpression [In, Yield, Await] : BitwiseANDExpression [?In, ?Yield, ?Await] BitwiseXORExpression [?In, ?Yield, ?Await] ^ BitwiseANDExpression [?In, ?Yield, ?Await] BitwiseORExpression [In, Yield, Await] : BitwiseXORExpression [?In, ?Yield, ?Await] BitwiseORExpression [?In, ?Yield, ?Await] | BitwiseXORExpression [?In, ?Yield, ?Await]

13.12.1 运行时语义:求值

BitwiseANDExpression : BitwiseANDExpression & EqualityExpression
  1. 返回 ?  EvaluateStringOrNumericBinaryExpression ( BitwiseANDExpression , &, EqualityExpression )。
BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression
  1. 返回 ?  EvaluateStringOrNumericBinaryExpression ( BitwiseXORExpression , ^, BitwiseANDExpression )。
BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression
  1. 返回 ?  EvaluateStringOrNumericBinaryExpression ( BitwiseORExpression , |, BitwiseXORExpression )。

13.13 二进制逻辑运算符

语法

LogicalANDExpression [In, Yield, Await] : BitwiseORExpression [?In, ?Yield, ?Await] LogicalANDExpression [?In, ?Yield, ?Await] && BitwiseORExpression [?In, ?Yield, ?Await] LogicalORExpression [In, Yield, Await] : LogicalANDExpression [?In, ?Yield, ?Await] LogicalORExpression [?In, ?Yield, ?Await] || LogicalANDExpression [?In, ?Yield, ?Await] CoalesceExpression [In, Yield, Await] : CoalesceExpressionHead [?In, ?Yield, ?Await] ?? BitwiseORExpression [?In, ?Yield, ?Await] CoalesceExpressionHead [In, Yield, Await] : CoalesceExpression [?In, ?Yield, ?Await] BitwiseORExpression [?In, ?Yield, ?Await] ShortCircuitExpression [In, Yield, Await] : LogicalORExpression [?In, ?Yield, ?Await] CoalesceExpression [?In, ?Yield, ?Await] 注释

&&|| 运算符生成的值不一定是布尔类型。生成的值始终是两个操作数表达式之一的值。

13.13.1 运行时语义:求值

LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
  1. lref 为 ?  Evaluation of LogicalANDExpression
  2. lval 为 ?  GetValue (lref)。
  3. lbool ToBoolean (lval)。
  4. 如果 lboolfalse,则返回 lval
  5. rref 为 ?  Evaluation of BitwiseORExpression
  6. 返回 ?  GetValue (rref)。
LogicalORExpression : LogicalORExpression || LogicalANDExpression
  1. lref 为 ?  Evaluation of LogicalORExpression
  2. lval 为 ?  GetValue (lref)。
  3. lbool ToBoolean (lval)。
  4. 如果 lbooltrue,则返回 lval
  5. rref 为 ?  Evaluation of LogicalANDExpression
  6. 返回 ?  GetValue (rref)。
CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
  1. lref 为 ?  Evaluation of CoalesceExpressionHead
  2. lval 为 ?  GetValue (lref)。
  3. 如果 lvalundefinednull,则
    1. rref 为 ?  Evaluation of BitwiseORExpression
    2. 返回 ?  GetValue (rref)。
  4. 否则,
    1. 返回 lval

13.14 条件操作符(? :

语法

ConditionalExpression [In, Yield, Await] : ShortCircuitExpression [?In, ?Yield, ?Await] ShortCircuitExpression [?In, ?Yield, ?Await] ? AssignmentExpression [+In, ?Yield, ?Await] : AssignmentExpression [?In, ?Yield, ?Await]

ECMAScript 中 ConditionalExpression 的语法与 C 和 Java 中的稍有不同。C 和 Java 允许第二个子表达式是一个 Expression ,但限制第三个表达式为 ConditionalExpression 。ECMAScript 这样设计的动机是允许赋值表达式由条件的任意一边控制,并且消除在中间表达式中出现逗号表达式这一困惑且几乎无用的情况。

13.14.1 运行时语义:求值

ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
  1. lref 为 ?  Evaluation of ShortCircuitExpression
  2. lval ToBoolean (? GetValue (lref))。
  3. 如果 lvaltrue,则
    1. trueRef 为 ?  Evaluation of 第一个 AssignmentExpression
    2. 返回 ?  GetValue (trueRef)。
  4. 否则,
    1. falseRef 为 ?  Evaluation of 第二个 AssignmentExpression
    2. 返回 ?  GetValue (falseRef)。

13.15 赋值操作符

语法

AssignmentExpression[In, Yield, Await] : ConditionalExpression[?In, ?Yield, ?Await] [+Yield] YieldExpression[?In, ?Await] ArrowFunction[?In, ?Yield, ?Await] AsyncArrowFunction[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] = AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] AssignmentOperator AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] &&= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ||= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ??= AssignmentExpression[?In, ?Yield, ?Await] AssignmentOperator : one of *= /= %= += -= <<= >>= >>>= &= ^= |= **=

13.15.1 静态语义:早期错误

AssignmentExpression : LeftHandSideExpression = AssignmentExpression

如果 LeftHandSideExpression ObjectLiteral ArrayLiteral ,则应用以下早期错误规则:

如果 LeftHandSideExpression 既不是 ObjectLiteral 也不是 ArrayLiteral ,则应用以下早期错误规则:

AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression

13.15.2 运行时语义:求值

AssignmentExpression : LeftHandSideExpression = AssignmentExpression
  1. 如果 LeftHandSideExpression 既不是 ObjectLiteral 也不是 ArrayLiteral ,则:
    1. lref是对 Evaluation LeftHandSideExpression 的求值。
    2. 如果 IsAnonymousFunctionDefinition ( AssignmentExpression )和 IsIdentifierRef LeftHandSideExpression 都为true,则:
      1. rval是对 NamedEvaluation ( AssignmentExpression ),带有参数lref.[[ReferencedName]]
    3. 否则,
      1. rref是对 Evaluation ( AssignmentExpression )的求值。
      2. rval是对 GetValue (rref)的求值。
    4. 执行 PutValue ( lrefrval)。
    5. 返回rval
  2. assignmentPattern成为 AssignmentPattern ,由 涵盖 LeftHandSideExpression
  3. rref是对 Evaluation ( AssignmentExpression )的求值。
  4. rval是对 GetValue (rref)的求值。
  5. 执行 DestructuringAssignmentEvaluation assignmentPattern,带有参数rval
  6. 返回rval
AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression
  1. lref是对 Evaluation LeftHandSideExpression 的求值。
  2. lval是对 GetValue (lref)的求值。
  3. rref是对 Evaluation AssignmentExpression 的求值。
  4. rval是对 GetValue (rref)的求值。
  5. assignmentOpText 源文本匹配 AssignmentOperator
  6. opText成为以下表格中与assignmentOpText关联的Unicode代码点序列:
    assignmentOpText opText
    **= **
    *= *
    /= /
    %= %
    += +
    -= -
    <<= <<
    >>= >>
    >>>= >>>
    &= &
    ^= ^
    |= |
  7. r是对 ApplyStringOrNumericBinaryOperator ( lvalopTextrval)的求值。
  8. 执行 PutValue ( lrefr)。
  9. 返回r
AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
  1. lref是对 Evaluation LeftHandSideExpression 的求值。
  2. lval是对 GetValue (lref)的求值。
  3. lbool ToBoolean (lval)的求值。
  4. 如果lboolfalse,返回lval
  5. 如果 IsAnonymousFunctionDefinition ( AssignmentExpression )为 true,且 IsIdentifierRef LeftHandSideExpression true,则:
    1. rval是对 NamedEvaluation ( AssignmentExpression ),带有参数 lref.[[ReferencedName]]
  6. 否则,
    1. rref是对 Evaluation AssignmentExpression 的求值。
    2. rval是对 GetValue (rref)的求值。
  7. 执行 PutValue ( lrefrval)。
  8. 返回rval
AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
  1. lref是对 Evaluation LeftHandSideExpression 的求值。
  2. lval是对 GetValue (lref)的求值。
  3. lbool ToBoolean (lval)的求值。
  4. 如果lbooltrue,返回lval
  5. 如果 IsAnonymousFunctionDefinition ( AssignmentExpression )为 true,且 IsIdentifierRef LeftHandSideExpression true,则:
    1. rval是对 NamedEvaluation ( AssignmentExpression ),带有参数 lref.[[ReferencedName]]
  6. 否则,
    1. rref是对 Evaluation AssignmentExpression 的求值。
    2. rval是对 GetValue (rref)的求值。
  7. 执行 PutValue ( lrefrval)。
  8. 返回rval
AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
  1. lref是对 Evaluation LeftHandSideExpression 的求值。
  2. lval是对 GetValue (lref)的求值。
  3. 如果 lval既不是undefined也不是null,返回 lval
  4. 如果 IsAnonymousFunctionDefinition ( AssignmentExpression )为 true,且 IsIdentifierRef LeftHandSideExpression true,则:
    1. rval是对 NamedEvaluation ( AssignmentExpression ),带有参数 lref.[[ReferencedName]]
  5. 否则,
    1. rref是对 Evaluation AssignmentExpression 的求值。
    2. rval是对 GetValue (rref)的求值。
  6. 执行 PutValue ( lrefrval)。
  7. 返回rval
注释

当此表达式出现在 严格模式代码 中时,如果步骤 1.d 2 2 2 2 中的 lref是不可解析的引用,则会抛出ReferenceError异常。此外,如果 lref在步骤 8 7 7 6 中引用了具有属性值{[[Writable]]:false}的数据属性、属性值{[[Set]]:undefined}的访问器属性或对于其 IsExtensible 谓词返回值为false的对象的不存在属性,在这些情况下,会抛出TypeError异常。

13.15.3 ApplyStringOrNumericBinaryOperator ( lval, opText, rval )

抽象操作 ApplyStringOrNumericBinaryOperator 接受参数 lval(一个 ECMAScript 语言值)、opText***/%+-<<>>>>>&^|)和 rval(一个 ECMAScript 语言值),并返回一个 正常完成记录,包含一个字符串、一个 BigInt 或一个数字,或者一个 抛出完成。调用时执行以下步骤:

  1. 如果 opText+,则
    1. lprim 为 ? ToPrimitive(lval)。
    2. rprim 为 ? ToPrimitive(rval)。
    3. 如果 lprim字符串rprim字符串,则
      1. lstr 为 ? ToString(lprim)。
      2. rstr 为 ? ToString(rprim)。
      3. 返回 lstrrstr字符串连接
    4. lval 设置为 lprim
    5. rval 设置为 rprim
  2. 注意:此时,它必须是一个数值运算。
  3. lnum 为 ? ToNumeric(lval)。
  4. rnum 为 ? ToNumeric(rval)。
  5. 如果 lnum类型rnum类型 不同,抛出一个 TypeError 异常。
  6. 如果 lnumBigInt,则
    1. 如果 opText**,返回 ? BigInt::exponentiate(lnum, rnum)。
    2. 如果 opText/,返回 ? BigInt::divide(lnum, rnum)。
    3. 如果 opText%,返回 ? BigInt::remainder(lnum, rnum)。
    4. 如果 opText>>>,返回 ? BigInt::unsignedRightShift(lnum, rnum)。
  7. operation 为与以下表格中的 opTextlnum类型 相关的抽象操作:
    opText 类型(lnum) operation
    ** Number Number::exponentiate
    * Number Number::multiply
    * BigInt BigInt::multiply
    / Number Number::divide
    % Number Number::remainder
    + Number Number::add
    + BigInt BigInt::add
    - Number Number::subtract
    - BigInt BigInt::subtract
    << Number Number::leftShift
    << BigInt BigInt::leftShift
    >> Number Number::signedRightShift
    >> BigInt BigInt::signedRightShift
    >>> Number Number::unsignedRightShift
    & Number Number::bitwiseAND
    & BigInt BigInt::bitwiseAND
    ^ Number Number::bitwiseXOR
    ^ BigInt BigInt::bitwiseXOR
    | Number Number::bitwiseOR
    | BigInt BigInt::bitwiseOR
  8. 返回 operation(lnum, rnum)。
注意 1

在步骤 ToPrimitive 中没有提供提示。除了日期对象之外,所有标准对象在没有提示的情况下都将其处理为 number;日期对象在没有提示的情况下将其处理为 string特殊对象 可能以其他方式处理没有提示的情况。

注意 2

步骤 1.c 与算法 IsLessThan 的步骤 3 不同,使用逻辑或运算而不是逻辑与运算。

13.15.4 EvaluateStringOrNumericBinaryExpression ( leftOperand, opText, rightOperand )

抽象操作 EvaluateStringOrNumericBinaryExpression 接受参数 leftOperand(一个解析节点)、opText(一个 Unicode 代码点序列)和 rightOperand(一个解析节点),返回一个正常完成记录,其中包含一个字符串、BigInt 或数字,或者一个中断完成记录。当被调用时,它执行以下步骤:

  1. lref 为 ? EvaluationleftOperand
  2. lval 为 ? GetValue(lref)。
  3. rref 为 ? EvaluationrightOperand
  4. rval 为 ? GetValue(rref)。
  5. 返回 ? ApplyStringOrNumericBinaryOperator(lval, opText, rval)。

13.15.5 解构赋值

补充语法

在处理以下产生式的实例时
AssignmentExpression : LeftHandSideExpression = AssignmentExpression
对于 LeftHandSideExpression 的解释将使用以下语法进行细化:

AssignmentPattern[Yield, Await] : ObjectAssignmentPattern[?Yield, ?Await] ArrayAssignmentPattern[?Yield, ?Await] ObjectAssignmentPattern[Yield, Await] : { } { AssignmentRestProperty[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] , AssignmentRestProperty[?Yield, ?Await]opt } ArrayAssignmentPattern[Yield, Await] : [ Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] [ AssignmentElementList[?Yield, ?Await] ] [ AssignmentElementList[?Yield, ?Await] , Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] AssignmentRestProperty[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] AssignmentPropertyList[Yield, Await] : AssignmentProperty[?Yield, ?Await] AssignmentPropertyList[?Yield, ?Await] , AssignmentProperty[?Yield, ?Await] AssignmentElementList[Yield, Await] : AssignmentElisionElement[?Yield, ?Await] AssignmentElementList[?Yield, ?Await] , AssignmentElisionElement[?Yield, ?Await] AssignmentElisionElement[Yield, Await] : Elisionopt AssignmentElement[?Yield, ?Await] AssignmentProperty[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt PropertyName[?Yield, ?Await] : AssignmentElement[?Yield, ?Await] AssignmentElement[Yield, Await] : DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt AssignmentRestElement[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] DestructuringAssignmentTarget[Yield, Await] : LeftHandSideExpression[?Yield, ?Await]

13.15.5.1 静态语义:早期错误

AssignmentProperty : IdentifierReference Initializeropt AssignmentRestProperty : ... DestructuringAssignmentTarget DestructuringAssignmentTarget : LeftHandSideExpression

如果 LeftHandSideExpressionObjectLiteralArrayLiteral,则适用以下早期错误规则:

如果 LeftHandSideExpression 既不是 ObjectLiteral 也不是 ArrayLiteral,则适用以下早期错误规则:

13.15.5.2 运行时语义:DestructuringAssignmentEvaluation

语法指引操作 DestructuringAssignmentEvaluation 接受参数 value(一个 ECMAScript 语言值 )并返回一个包含 正常完成 unused 或一个 突然完成 。它通过以下生成规则分段定义:

ObjectAssignmentPattern : { }
  1. 执行 ? RequireObjectCoercible (value)。
  2. 返回 unused
ObjectAssignmentPattern : { AssignmentPropertyList } { AssignmentPropertyList , }
  1. 执行 ? RequireObjectCoercible (value)。
  2. 执行 ? PropertyDestructuringAssignmentEvaluation of AssignmentPropertyList with argument value
  3. 返回 unused
ObjectAssignmentPattern : { AssignmentRestProperty }
  1. 执行 ? RequireObjectCoercible (value)。
  2. excludedNames 成为一个新的空的 列表
  3. 返回 ? RestDestructuringAssignmentEvaluation of AssignmentRestProperty with arguments valueexcludedNames
ObjectAssignmentPattern : { AssignmentPropertyList , AssignmentRestProperty }
  1. 执行 ? RequireObjectCoercible (value)。
  2. excludedNames 成为 ? PropertyDestructuringAssignmentEvaluation of AssignmentPropertyList with argument value
  3. 返回 ? RestDestructuringAssignmentEvaluation of AssignmentRestProperty with arguments valueexcludedNames
ArrayAssignmentPattern : [ ]
  1. iteratorRecord 成为 ? GetIterator (value, sync)。
  2. 返回 ? IteratorClose (iteratorRecord, NormalCompletion (unused))。
ArrayAssignmentPattern : [ Elision ]
  1. iteratorRecord 成为 ? GetIterator (value, sync)。
  2. result 成为 Completion ( IteratorDestructuringAssignmentEvaluation of Elision with argument iteratorRecord)。
  3. 如果 iteratorRecord.[[Done]]false,返回 ? IteratorClose (iteratorRecord, result)。
  4. 返回 result
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
  1. iteratorRecord 成为 ? GetIterator (value, sync)。
  2. 如果 Elision 存在,则
    1. status 成为 Completion ( IteratorDestructuringAssignmentEvaluation of Elision with argument iteratorRecord)。
    2. 如果 status 是一个 突然完成 ,则
      1. 断言: iteratorRecord.[[Done]]true
      2. 返回 ? status
  3. result 成为 Completion ( IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with argument iteratorRecord)。
  4. 如果 iteratorRecord.[[Done]]false,返回 ? IteratorClose (iteratorRecord, result)。
  5. 返回 result
ArrayAssignmentPattern : [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
  1. iteratorRecord 成为 ? GetIterator (value, sync)。
  2. status 成为 Completion ( IteratorDestructuringAssignmentEvaluation of AssignmentElementList with argument iteratorRecord)。
  3. 如果 status 是一个 突然完成 ,则
    1. 如果 iteratorRecord.[[Done]]false,返回 ? IteratorClose (iteratorRecord, status)。
    2. 返回 ? status
  4. 如果 Elision 存在,则
    1. 设置 status Completion ( IteratorDestructuringAssignmentEvaluation of Elision with argument iteratorRecord)。
    2. 如果 status 是一个 突然完成 ,则
      1. 断言: iteratorRecord.[[Done]]true
      2. 返回 ? status
  5. 如果 AssignmentRestElement 存在,则
    1. 设置 status Completion ( IteratorDestructuringAssignmentEvaluation of AssignmentRestElement with argument iteratorRecord)。
  6. 如果 iteratorRecord.[[Done]]false,返回 ? IteratorClose (iteratorRecord, status)。
  7. 返回 ? status

13.15.5.3 运行时语义:属性解构赋值求值

语法指导操作 PropertyDestructuringAssignmentEvaluation 接受参数 value (一个 ECMAScript 语言值),并返回一个 包含的正常完成 属性键列表 或一个 异常完成。它收集所有解构的 属性键。它的定义如下:

AssignmentPropertyList : AssignmentPropertyList , AssignmentProperty
  1. propertyNames 是 ? PropertyDestructuringAssignmentEvaluationAssignmentPropertyList 调用时的参数 value
  2. nextNames 是 ? PropertyDestructuringAssignmentEvaluationAssignmentProperty 调用时的参数 value
  3. 返回 propertyNamesnextNames列表连接
AssignmentProperty : IdentifierReference Initializeropt
  1. PStringValueIdentifierReference
  2. lref 是 ? ResolveBinding(P)。
  3. v 是 ? GetV(value, P)。
  4. 如果 Initializer 存在并且 vundefined,则
    1. 如果 IsAnonymousFunctionDefinition(Initializer) 为 true,则
      1. v 设置为 ? NamedEvaluationInitializer 参数为 P
    2. 否则,
      1. defaultValue 是 ? EvaluationInitializer
      2. v 设置为 ? GetValue(defaultValue)。
  5. 执行 ? PutValue(lref, v)。
  6. 返回 « P »。
AssignmentProperty : PropertyName : AssignmentElement
  1. name 是 ? EvaluationPropertyName
  2. 执行 ? KeyedDestructuringAssignmentEvaluationAssignmentElement 参数为 valuename
  3. 返回 « name »。

13.15.5.4 运行时语义:RestDestructuringAssignmentEvaluation

语法指导操作 RestDestructuringAssignmentEvaluation 接受参数 value (一个 ECMAScript 语言值) 和 excludedNames(一个 列表属性键),并返回一个 包含 unused 的正常完成记录,或一个 异常完成。它的定义如下:

AssignmentRestProperty : ... DestructuringAssignmentTarget
  1. lref 是 ? EvaluationDestructuringAssignmentTarget
  2. restObjOrdinaryObjectCreate(%Object.prototype%)。
  3. 执行 ? CopyDataProperties(restObj, value, excludedNames)。
  4. 返回 ? PutValue(lref, restObj)。

13.15.5.5 运行时语义:IteratorDestructuringAssignmentEvaluation

语法指导操作 IteratorDestructuringAssignmentEvaluation 接受参数 iteratorRecord(一个 迭代器记录)并返回一个 包含 unused 的正常完成记录或一个 异常完成。它的定义如下:

AssignmentElementList : AssignmentElisionElement
  1. 返回 ? IteratorDestructuringAssignmentEvaluationAssignmentElisionElement 传入参数 iteratorRecord
AssignmentElementList : AssignmentElementList , AssignmentElisionElement
  1. 执行 ? IteratorDestructuringAssignmentEvaluationAssignmentElementList 传入参数 iteratorRecord
  2. 返回 ? IteratorDestructuringAssignmentEvaluationAssignmentElisionElement 传入参数 iteratorRecord
AssignmentElisionElement : AssignmentElement
  1. 返回 ? IteratorDestructuringAssignmentEvaluationAssignmentElement 传入参数 iteratorRecord
AssignmentElisionElement : Elision AssignmentElement
  1. 执行 ? IteratorDestructuringAssignmentEvaluationElision 传入参数 iteratorRecord
  2. 返回 ? IteratorDestructuringAssignmentEvaluationAssignmentElement 传入参数 iteratorRecord
Elision : ,
  1. 如果 iteratorRecord.[[Done]]false,那么
    1. nextCompletion(IteratorStep(iteratorRecord))。
    2. 如果 next 是一个 异常完成,设置 iteratorRecord.[[Done]]true
    3. ReturnIfAbrupt(next)。
    4. 如果 nextfalse,设置 iteratorRecord.[[Done]]true
  2. 返回 unused
Elision : Elision ,
  1. 执行 ? IteratorDestructuringAssignmentEvaluationElision 传入参数 iteratorRecord
  2. 如果 iteratorRecord.[[Done]]false,那么
    1. nextCompletion(IteratorStep(iteratorRecord))。
    2. 如果 next 是一个 异常完成,设置 iteratorRecord.[[Done]]true
    3. ReturnIfAbrupt(next)。
    4. 如果 nextfalse,设置 iteratorRecord.[[Done]]true
  3. 返回 unused
AssignmentElement : DestructuringAssignmentTarget Initializeropt
  1. 如果 DestructuringAssignmentTarget 既不是一个 ObjectLiteral 也不是一个 ArrayLiteral,那么
    1. lref 为 ? EvaluationDestructuringAssignmentTarget
  2. valueundefined
  3. 如果 iteratorRecord.[[Done]]false,那么
    1. next 为 ? IteratorStepValueiteratorRecord
    2. 如果 next 不是 done,那么
      1. 设置 valuenext
  4. 如果 Initializer 存在并且 valueundefined,那么
    1. 如果 IsAnonymousFunctionDefinition(Initializer) 是 true 并且 IsIdentifierRefDestructuringAssignmentTargettrue,那么
      1. v 为 ? NamedEvaluationInitializer 传入参数 lref.[[ReferencedName]]
    2. 否则,
      1. defaultValue 为 ? EvaluationInitializer
      2. v 为 ? GetValue(defaultValue)。
  5. 否则,
    1. vvalue
  6. 如果 DestructuringAssignmentTarget 是一个 ObjectLiteral 或一个 ArrayLiteral,那么
    1. nestedAssignmentPattern 为一个 AssignmentPattern, 它被 覆盖DestructuringAssignmentTarget
    2. 返回 ? DestructuringAssignmentEvaluationnestedAssignmentPattern 传入参数 v
  7. 返回 ? PutValue(lref, v)。
注释

从左到右的求值顺序通过在访问迭代器或求值 DestructuringAssignmentTarget 不是解构模式之前先求值 Initializer 来保持。

AssignmentRestElement : ... DestructuringAssignmentTarget
  1. 如果 DestructuringAssignmentTarget 既不是一个 ObjectLiteral 也不是一个 ArrayLiteral,那么
    1. lref 为 ? EvaluationDestructuringAssignmentTarget
  2. A 为 ! ArrayCreate(0)。
  3. n 为 0。
  4. 重复,直到 iteratorRecord.[[Done]]false
    1. next 为 ? IteratorStepValueiteratorRecord
    2. 如果 next 不是 done,那么
      1. 执行 ! CreateDataPropertyOrThrowA, ! ToString𝔽nnext
      2. 设置 nn + 1。
  5. 如果 DestructuringAssignmentTarget 既不是一个 ObjectLiteral 也不是一个 ArrayLiteral,那么
    1. 返回 ? PutValuelrefA
  6. nestedAssignmentPattern 为一个 AssignmentPattern, 它被 覆盖DestructuringAssignmentTarget
  7. 返回 ? DestructuringAssignmentEvaluationnestedAssignmentPattern 传入参数 A

13.15.5.6 运行时语义:KeyedDestructuringAssignmentEvaluation

语法指向操作 KeyedDestructuringAssignmentEvaluation 接受参数 value(一个 ECMAScript 语言值 )和 propertyName(一个 属性键 ),并返回一个 包含的正常完成 unused 异常完成 。它逐一定义在以下产生式上:

AssignmentElement : DestructuringAssignmentTarget Initializer opt
  1. 如果 DestructuringAssignmentTarget 既不是 ObjectLiteral 也不是 ArrayLiteral ,那么
    1. lref 为 ? Evaluation DestructuringAssignmentTarget
  2. v 为 ? GetV valuepropertyName
  3. 如果 Initializer 存在并且 vundefined,那么
    1. 如果 IsAnonymousFunctionDefinition Initializer 并且 IsIdentifierRef DestructuringAssignmentTarget 都为 true,那么
      1. rhsValue 为 ? NamedEvaluation Initializer 传入参数 lref.[[ReferencedName]]
    2. 否则,
      1. defaultValue 为 ? Evaluation Initializer
      2. rhsValue 为 ? GetValue defaultValue
  4. 否则,
    1. rhsValuev
  5. 如果 DestructuringAssignmentTarget 是一个 ObjectLiteral ArrayLiteral ,那么
    1. assignmentPattern AssignmentPattern ,它被 覆盖 DestructuringAssignmentTarget
    2. 返回 ? DestructuringAssignmentEvaluation assignmentPattern 传入参数 rhsValue
  6. 返回 ? PutValue lrefrhsValue

13.16 逗号操作符 (,)

语法

Expression [In, Yield, Await] : AssignmentExpression [?In, ?Yield, ?Await] Expression [?In, ?Yield, ?Await] , AssignmentExpression [?In, ?Yield, ?Await]

13.16.1 运行时语义:Evaluation

Expression : Expression , AssignmentExpression
  1. lref 为 ?  Evaluation Expression
  2. 执行 ?  GetValue (lref)。
  3. rref 为 ?  Evaluation AssignmentExpression
  4. 返回 ?  GetValue (rref)。
注意

GetValue 必须被调用,即使其值未被使用,因为它可能具有可观察的副作用。

14 ECMAScript 语言:语句和声明

语法

Statement[Yield, Await, Return] : BlockStatement[?Yield, ?Await, ?Return] VariableStatement[?Yield, ?Await] EmptyStatement ExpressionStatement[?Yield, ?Await] IfStatement[?Yield, ?Await, ?Return] BreakableStatement[?Yield, ?Await, ?Return] ContinueStatement[?Yield, ?Await] BreakStatement[?Yield, ?Await] [+Return] ReturnStatement[?Yield, ?Await] WithStatement[?Yield, ?Await, ?Return] LabelledStatement[?Yield, ?Await, ?Return] ThrowStatement[?Yield, ?Await] TryStatement[?Yield, ?Await, ?Return] DebuggerStatement Declaration[Yield, Await] : HoistableDeclaration[?Yield, ?Await, ~Default] ClassDeclaration[?Yield, ?Await, ~Default] LexicalDeclaration[+In, ?Yield, ?Await] HoistableDeclaration[Yield, Await, Default] : FunctionDeclaration[?Yield, ?Await, ?Default] GeneratorDeclaration[?Yield, ?Await, ?Default] AsyncFunctionDeclaration[?Yield, ?Await, ?Default] AsyncGeneratorDeclaration[?Yield, ?Await, ?Default] BreakableStatement[Yield, Await, Return] : IterationStatement[?Yield, ?Await, ?Return] SwitchStatement[?Yield, ?Await, ?Return]

14.1 语句语义

14.1.1 运行时语义:求值

HoistableDeclaration : GeneratorDeclaration AsyncFunctionDeclaration AsyncGeneratorDeclaration
  1. 返回 empty
HoistableDeclaration : FunctionDeclaration
  1. 返回 ? 求值 of FunctionDeclaration
BreakableStatement : IterationStatement SwitchStatement
  1. newLabelSet 为一个空的 List
  2. 返回 ? LabelledEvaluation of this BreakableStatement with argument newLabelSet

14.2

语法

BlockStatement[Yield, Await, Return] : Block[?Yield, ?Await, ?Return] Block[Yield, Await, Return] : { StatementList[?Yield, ?Await, ?Return]opt } StatementList[Yield, Await, Return] : StatementListItem[?Yield, ?Await, ?Return] StatementList[?Yield, ?Await, ?Return] StatementListItem[?Yield, ?Await, ?Return] StatementListItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] Declaration[?Yield, ?Await]

14.2.1 静态语义:早期错误

Block : { StatementList }

14.2.2 运行时语义:求值

Block : { }
  1. 返回 empty
Block : { StatementList }
  1. oldEnv运行中的执行上下文的 LexicalEnvironment。
  2. blockEnvNewDeclarativeEnvironment(oldEnv)。
  3. 执行 BlockDeclarationInstantiation(StatementList, blockEnv)。
  4. 运行中的执行上下文的 LexicalEnvironment 设置为 blockEnv
  5. blockValueCompletion(求值 of StatementList)。
  6. 运行中的执行上下文的 LexicalEnvironment 设置为 oldEnv
  7. 返回 ? blockValue
注释 1

无论控制如何离开 Block,LexicalEnvironment 总是恢复到其以前的状态。

StatementList : StatementList StatementListItem
  1. sl 为 ? 求值 of StatementList
  2. sCompletion(求值 of StatementListItem)。
  3. 返回 ? UpdateEmpty(s, sl)。
注释 2

StatementList 的值是 StatementList 中最后一个产生值的项的值。例如,以下对 eval 函数的调用都返回值 1:

eval("1;;;;;")
eval("1;{}")
eval("1;var a;")

14.2.3 BlockDeclarationInstantiation ( code, env )

抽象操作 BlockDeclarationInstantiation 接受参数 code(一个 解析节点)和 env (一个 声明性环境记录)并返回 unusedcode 是与块体对应的 解析节点env 是将在其中创建绑定的 环境记录

注释

BlockCaseBlock 被求值时,会创建一个新的 声明性环境记录,并且块作用域内的每个变量、常量、函数或类声明的绑定会在 环境记录 中实例化。

当调用时,它执行以下步骤:

  1. declarationscodeLexicallyScopedDeclarations
  2. privateEnv运行中的执行上下文的 PrivateEnvironment。
  3. 对于 declarations 的每个元素 d,执行
    1. 对于 dBoundNames 的每个元素 dn,执行
      1. 如果 dIsConstantDeclarationtrue,则
        1. 执行 ! env.CreateImmutableBinding(dn, true)。
      2. 否则,
        1. 执行 ! env.CreateMutableBinding(dn, false)。注意:此步骤在 B.3.2.6 中被替换。
    2. 如果 dFunctionDeclarationGeneratorDeclarationAsyncFunctionDeclarationAsyncGeneratorDeclaration,则
      1. fndBoundNames 的唯一元素。
      2. fodInstantiateFunctionObject,参数为 envprivateEnv
      3. 执行 ! env.InitializeBinding(fn, fo)。注意:此步骤在 B.3.2.6 中被替换。
  4. 返回 unused

14.3 声明和变量语句

14.3.1 Let 和 Const 声明

注释

letconst 声明定义的变量作用域为 运行中的执行上下文的 LexicalEnvironment。变量在其包含的 环境记录 被实例化时创建,但在变量的 LexicalBinding 被求值之前不能以任何方式访问。带有 InitializerLexicalBinding 定义的变量在 Initializer 被求值时被赋值,而不是在变量创建时。如果 let 声明中的 LexicalBinding 没有 Initializer,则变量在 LexicalBinding 被求值时被赋值为 undefined

语法

LexicalDeclaration[In, Yield, Await] : LetOrConst BindingList[?In, ?Yield, ?Await] ; LetOrConst : let const BindingList[In, Yield, Await] : LexicalBinding[?In, ?Yield, ?Await] BindingList[?In, ?Yield, ?Await] , LexicalBinding[?In, ?Yield, ?Await] LexicalBinding[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

14.3.1.1 静态语义:早期错误

LexicalDeclaration : LetOrConst BindingList ; LexicalBinding : BindingIdentifier Initializeropt

14.3.1.2 运行时语义:求值

LexicalDeclaration : LetOrConst BindingList ;
  1. 执行 ? 求值 of BindingList
  2. 返回 empty
BindingList : BindingList , LexicalBinding
  1. 执行 ? 求值 of BindingList
  2. 返回 ? 求值 of LexicalBinding
LexicalBinding : BindingIdentifier
  1. lhs 为 ! ResolveBinding(StringValue of BindingIdentifier)。
  2. 执行 ! InitializeReferencedBinding(lhs, undefined)。
  3. 返回 empty
注释

一个 静态语义 规则确保这种形式的 LexicalBinding 永远不会出现在 const 声明中。

LexicalBinding : BindingIdentifier Initializer
  1. bindingIdStringValue of BindingIdentifier
  2. lhs 为 ! ResolveBinding(bindingId)。
  3. 如果 IsAnonymousFunctionDefinition(Initializer) is true,则
    1. value 为 ? NamedEvaluation of Initializer with argument bindingId
  4. 否则,
    1. rhs 为 ? 求值 of Initializer
    2. value 为 ? GetValue(rhs)。
  5. 执行 ! InitializeReferencedBinding(lhs, value)。
  6. 返回 empty
LexicalBinding : BindingPattern Initializer
  1. rhs 为 ? 求值 of Initializer
  2. value 为 ? GetValue(rhs)。
  3. env运行中的执行上下文的 LexicalEnvironment。
  4. 返回 ? BindingInitialization of BindingPattern with arguments value and env

14.3.2 变量语句

注释

一个 var 语句声明的变量作用域为 运行中的执行上下文的 VariableEnvironment。Var 变量在其包含的 环境记录 被实例化时创建,并初始化为 undefined。在任何 VariableEnvironment 的作用域内,一个共同的 BindingIdentifier 可能出现在多个 VariableDeclaration 中,但这些声明共同定义了一个变量。带有 InitializerVariableDeclaration 定义的变量在 Initializer 被求值时被赋值,而不是在变量创建时。

语法

VariableStatement[Yield, Await] : var VariableDeclarationList[+In, ?Yield, ?Await] ; VariableDeclarationList[In, Yield, Await] : VariableDeclaration[?In, ?Yield, ?Await] VariableDeclarationList[?In, ?Yield, ?Await] , VariableDeclaration[?In, ?Yield, ?Await] VariableDeclaration[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

14.3.2.1 运行时语义:求值

VariableStatement : var VariableDeclarationList ;
  1. 执行 ? 求值 of VariableDeclarationList
  2. 返回 empty
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. 执行 ? 求值 of VariableDeclarationList
  2. 返回 ? 求值 of VariableDeclaration
VariableDeclaration : BindingIdentifier
  1. 返回 empty
VariableDeclaration : BindingIdentifier Initializer
  1. bindingIdStringValue of BindingIdentifier
  2. lhs 为 ? ResolveBinding(bindingId)。
  3. 如果 IsAnonymousFunctionDefinition(Initializer) is true,则
    1. value 为 ? NamedEvaluation of Initializer with argument bindingId
  4. 否则,
    1. rhs 为 ? 求值 of Initializer
    2. value 为 ? GetValue(rhs)。
  5. 执行 ? PutValue(lhs, value)。
  6. 返回 empty
注释

如果一个 VariableDeclaration 嵌套在一个 with 语句中,并且 BindingIdentifierVariableDeclaration 中与 with 语句的绑定对象的 属性名 相同,那么步骤 5 将把 value 赋值给该属性,而不是赋值给 VariableEnvironment 绑定。

VariableDeclaration : BindingPattern Initializer
  1. rhs 为 ? 求值 of Initializer
  2. rval 为 ? GetValue(rhs)。
  3. 返回 ? BindingInitialization of BindingPattern with arguments rval and undefined

14.3.3 解构绑定模式

语法

BindingPattern[Yield, Await] : ObjectBindingPattern[?Yield, ?Await] ArrayBindingPattern[?Yield, ?Await] ObjectBindingPattern[Yield, Await] : { } { BindingRestProperty[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] , BindingRestProperty[?Yield, ?Await]opt } ArrayBindingPattern[Yield, Await] : [ Elisionopt BindingRestElement[?Yield, ?Await]opt ] [ BindingElementList[?Yield, ?Await] ] [ BindingElementList[?Yield, ?Await] , Elisionopt BindingRestElement[?Yield, ?Await]opt ] BindingRestProperty[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] BindingPropertyList[Yield, Await] : BindingProperty[?Yield, ?Await] BindingPropertyList[?Yield, ?Await] , BindingProperty[?Yield, ?Await] BindingElementList[Yield, Await] : BindingElisionElement[?Yield, ?Await] BindingElementList[?Yield, ?Await] , BindingElisionElement[?Yield, ?Await] BindingElisionElement[Yield, Await] : Elisionopt BindingElement[?Yield, ?Await] BindingProperty[Yield, Await] : SingleNameBinding[?Yield, ?Await] PropertyName[?Yield, ?Await] : BindingElement[?Yield, ?Await] BindingElement[Yield, Await] : SingleNameBinding[?Yield, ?Await] BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt SingleNameBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt BindingRestElement[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] ... BindingPattern[?Yield, ?Await]

14.3.3.1 运行时语义:属性绑定初始化

属性绑定初始化是一个 语法导向操作,它接受参数 value(一个 ECMAScript 语言值)和 environment(一个 环境记录undefined),并返回一个 正常完成 包含一个 列表属性键 或一个 突然完成。它收集所有绑定属性名的列表。它在以下产生式上分段定义:

BindingPropertyList : BindingPropertyList , BindingProperty
  1. boundNames 为 ? 属性绑定初始化 of BindingPropertyList 使用参数 valueenvironment
  2. nextNames 为 ? 属性绑定初始化 of BindingProperty 使用参数 valueenvironment
  3. 返回 boundNamesnextNames列表连接
BindingProperty : SingleNameBinding
  1. nameSingleNameBindingBoundNames 的唯一元素。
  2. 执行 ? 键绑定初始化 of SingleNameBinding 使用参数 valueenvironmentname
  3. 返回 « name »。
BindingProperty : PropertyName : BindingElement
  1. P 为 ? 求值 of PropertyName
  2. 执行 ? 键绑定初始化 of BindingElement 使用参数 valueenvironmentP
  3. 返回 « P »。

14.3.3.2 运行时语义:剩余绑定初始化

剩余绑定初始化是一个 语法导向操作,它接受参数 value(一个 ECMAScript 语言值)、environment(一个 环境记录undefined)和 excludedNames(一个 列表属性键),并返回一个 正常完成 包含 unused 或一个 突然完成。它在以下产生式上分段定义:

BindingRestProperty : ... BindingIdentifier
  1. lhs 为 ? ResolveBinding(StringValue of BindingIdentifier, environment)。
  2. restObjOrdinaryObjectCreate(%Object.prototype%)。
  3. 执行 ? CopyDataProperties(restObj, value, excludedNames)。
  4. 如果 environmentundefined, 返回 ? PutValue(lhs, restObj)。
  5. 返回 ? InitializeReferencedBinding(lhs, restObj)。

14.3.3.3 运行时语义:键绑定初始化

键绑定初始化是一个 语法导向操作,它接受参数 value(一个 ECMAScript 语言值)、environment(一个 环境记录undefined)和 propertyName(一个 属性键),并返回一个 正常完成 包含 unused 或一个 突然完成。它定义在以下产生式上分段:

注释

undefined 作为 environment 传递时,表示应该使用 PutValue 操作来分配初始化值。这种情况发生在 非严格函数 的形式参数列表中。在这种情况下,形式参数绑定是预初始化的,以处理多个参数具有相同名称的可能性。

它在以下产生式上分段定义:

BindingElement : BindingPattern Initializeropt
  1. v 为 ? GetV(value, propertyName)。
  2. 如果 Initializer 存在且 vundefined,则
    1. defaultValue 为 ? 求值 of Initializer
    2. 设置 v 为 ? GetValue(defaultValue)。
  3. 返回 ? 绑定初始化 of BindingPattern 使用参数 venvironment
SingleNameBinding : BindingIdentifier Initializeropt
  1. bindingIdStringValue of BindingIdentifier
  2. lhs 为 ? ResolveBinding(bindingId, environment)。
  3. v 为 ? GetV(value, propertyName)。
  4. 如果 Initializer 存在且 vundefined,则
    1. 如果 IsAnonymousFunctionDefinition(Initializer) is true,则
      1. 设置 v 为 ? NamedEvaluation of Initializer with argument bindingId
    2. 否则,
      1. defaultValue 为 ? 求值 of Initializer
      2. 设置 v 为 ? GetValue(defaultValue)。
  5. 如果 environmentundefined, 返回 ? PutValue(lhs, v)。
  6. 返回 ? InitializeReferencedBinding(lhs, v)。

14.4 空语句

语法

EmptyStatement : ;

14.4.1 运行时语义:求值

EmptyStatement : ;
  1. 返回 empty

14.5 表达式语句

语法

ExpressionStatement[Yield, Await] : [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }] Expression[+In, ?Yield, ?Await] ; 注释

一个 ExpressionStatement 不能以一个 U+007B (LEFT CURLY BRACKET) 开始,因为这可能会使其与一个 Block 产生歧义。一个 ExpressionStatement 不能以 functionclass 关键字 开始,因为这可能会使其与一个 FunctionDeclaration、一个 GeneratorDeclaration 或一个 ClassDeclaration 产生歧义。一个 ExpressionStatement 不能以 async function 开始,因为这可能会使其与一个 AsyncFunctionDeclaration 或一个 AsyncGeneratorDeclaration 产生歧义。一个 ExpressionStatement 不能以两个标记序列 let [ 开始,因为这可能会使其与一个 let LexicalDeclaration 的第一个 LexicalBinding 是一个 ArrayBindingPattern 产生歧义。

14.5.1 运行时语义:求值

ExpressionStatement : Expression ;
  1. exprRef 为 ? 求值 of Expression
  2. 返回 ? GetValue(exprRef)。

14.6 if 语句

语法

IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [lookahead ≠ else] 注意
前瞻限制 [lookahead ≠ else] 以通常的方式解决了经典的“悬空 else”问题。也就是说,当关联的 if 选择不明确时,else 与最近的(最内层的)候选 if 相关联。

14.6.1 静态语义:早期错误

IfStatement : if ( Expression ) Statement else Statement IfStatement : if ( Expression ) Statement 注意

只有在实现 B.3.1 中指定的扩展时,才需要应用此规则。

14.6.2 运行时语义:求值

IfStatement : if ( Expression ) Statement else Statement
  1. exprRef 为 ? 求值 of Expression.
  2. exprValueToBoolean(? GetValue(exprRef)).
  3. 如果 exprValuetrue,则
    1. stmtCompletionCompletion(求值 of the first Statement).
  4. 否则
    1. stmtCompletionCompletion(求值 of the second Statement).
  5. 返回 ? UpdateEmpty(stmtCompletion, undefined).
IfStatement : if ( Expression ) Statement
  1. exprRef 为 ? 求值 of Expression.
  2. exprValueToBoolean(? GetValue(exprRef)).
  3. 如果 exprValuefalse,则
    1. 返回 undefined.
  4. 否则
    1. stmtCompletionCompletion(求值 of Statement).
    2. 返回 ? UpdateEmpty(stmtCompletion, undefined).

14.7 迭代语句

语法

IterationStatement[Yield, Await, Return] : DoWhileStatement[?Yield, ?Await, ?Return] WhileStatement[?Yield, ?Await, ?Return] ForStatement[?Yield, ?Await, ?Return] ForInOfStatement[?Yield, ?Await, ?Return]

14.7.1 语义

14.7.1.1 LoopContinues ( completion, labelSet )

抽象操作 LoopContinues 接受参数 completion(一个 Completion Record)和 labelSet(一个 List of Strings)并返回一个 Boolean。它在调用时执行以下步骤:

  1. 如果 completion 是一个 normal completion,返回 true
  2. 如果 completion 不是一个 continue completion,返回 false
  3. 如果 completion.[[Target]]empty,返回 true
  4. 如果 labelSet 包含 completion.[[Target]],返回 true
  5. 返回 false
注意

Statement 部分的 IterationStatement 中,ContinueStatement 可以用于开始一个新的迭代。

14.7.1.2 运行时语义:LoopEvaluation

语法导向操作 LoopEvaluation 接受参数 labelSet(一个 List of Strings)并返回一个 normal completion containing 一个 ECMAScript language value 或一个 abrupt completion。它在以下产生式上定义:

IterationStatement : DoWhileStatement
  1. 返回 ? DoWhileLoopEvaluation of DoWhileStatement with argument labelSet.
IterationStatement : WhileStatement
  1. 返回 ? WhileLoopEvaluation of WhileStatement with argument labelSet.
IterationStatement : ForStatement
  1. 返回 ? ForLoopEvaluation of ForStatement with argument labelSet.
IterationStatement : ForInOfStatement
  1. 返回 ? ForInOfLoopEvaluation of ForInOfStatement with argument labelSet.

14.7.2 do-while 语句

语法

DoWhileStatement[Yield, Await, Return] : do Statement[?Yield, ?Await, ?Return] while ( Expression[+In, ?Yield, ?Await] ) ;

14.7.2.1 静态语义:早期错误

DoWhileStatement : do Statement while ( Expression ) ; 注意

只有在实现 B.3.1 中指定的扩展时,才需要应用此规则。

14.7.2.2 运行时语义:DoWhileLoopEvaluation

语法导向操作 DoWhileLoopEvaluation 接受参数 labelSet(一个 List of Strings)并返回一个 normal completion containing 一个 ECMAScript language value 或一个 abrupt completion。它在以下产生式上定义:

DoWhileStatement : do Statement while ( Expression ) ;
  1. Vundefined
  2. 重复,
    1. stmtResultCompletion(求值 of Statement)。
    2. 如果 LoopContinues(stmtResult, labelSet) 是 false,返回 ? UpdateEmpty(stmtResult, V)。
    3. 如果 stmtResult.[[Value]] 不是 empty,设 VstmtResult.[[Value]]
    4. exprRef 为 ? 求值 of Expression
    5. exprValue 为 ? GetValue(exprRef)。
    6. 如果 ToBoolean(exprValue) 是 false,返回 V

14.7.3 while 语句

语法

WhileStatement[Yield, Await, Return] : while ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]

14.7.3.1 静态语义:早期错误

WhileStatement : while ( Expression ) Statement 注意

只有在实现 B.3.1 中指定的扩展时,才需要应用此规则。

14.7.3.2 运行时语义:WhileLoopEvaluation

语法导向操作 WhileLoopEvaluation 接受参数 labelSet(一个 List of Strings)并返回一个 normal completion containing 一个 ECMAScript language value 或一个 abrupt completion。它在以下产生式上定义:

WhileStatement : while ( Expression ) Statement
  1. Vundefined
  2. 重复,
    1. exprRef 为 ? 求值 of Expression
    2. exprValue 为 ? GetValue(exprRef)。
    3. 如果 ToBoolean(exprValue) 是 false,返回 V
    4. stmtResultCompletion(求值 of Statement)。
    5. 如果 LoopContinues(stmtResult, labelSet) 是 false,返回 ? UpdateEmpty(stmtResult, V)。
    6. 如果 stmtResult.[[Value]] 不是 empty,设 VstmtResult.[[Value]]

14.7.4 for 语句

语法

ForStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] Expression[~In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( var VariableDeclarationList[~In, ?Yield, ?Await] ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( LexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return]

14.7.4.1 静态语义:早期错误

ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement 注意

只有在实现 B.3.1 中指定的扩展时,才需要应用此规则。

ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement

14.7.4.2 运行时语义:ForLoopEvaluation

语法导向操作 ForLoopEvaluation 接受参数 labelSet(一个 List of Strings)并返回一个 normal completion containing 一个 ECMAScript language value 或一个 abrupt completion。它在以下产生式上定义:

ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. 如果第一个 Expression 存在,则
    1. exprRef 为 ? 求值 of the first Expression
    2. 执行 ? GetValue(exprRef)。
  2. 如果第二个 Expression 存在,设 test 为第二个 Expression;否则,设 testempty
  3. 如果第三个 Expression 存在,设 increment 为第三个 Expression;否则,设 incrementempty
  4. 返回 ? ForBodyEvaluation(test, increment, Statement, « », labelSet)。
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. 执行 ? 求值 of VariableDeclarationList
  2. 如果第一个 Expression 存在,设 test 为第一个 Expression;否则,设 testempty
  3. 如果第二个 Expression 存在,设 increment 为第二个 Expression;否则,设 incrementempty
  4. 返回 ? ForBodyEvaluation(test, increment, Statement, « », labelSet)。
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. oldEnv运行执行上下文的词法环境。
  2. loopEnvNewDeclarativeEnvironment(oldEnv)。
  3. isConstIsConstantDeclaration of LexicalDeclaration
  4. boundNamesBoundNames of LexicalDeclaration
  5. 对于 boundNames 的每个元素 dn,执行
    1. 如果 isConsttrue,则
      1. 执行 ! loopEnv.CreateImmutableBinding(dn, true)。
    2. 否则,
      1. 执行 ! loopEnv.CreateMutableBinding(dn, false)。
  6. 运行执行上下文的词法环境设置为 loopEnv
  7. forDclCompletion(求值 of LexicalDeclaration)。
  8. 如果 forDcl 是一个 abrupt completion,则
    1. 运行执行上下文的词法环境设置为 oldEnv
    2. 返回 ? forDcl
  9. 如果 isConstfalse,设 perIterationLetsboundNames;否则设 perIterationLets 为 一个新的空 List
  10. 如果第一个 Expression 存在,设 test 为第一个 Expression;否则,设 testempty
  11. 如果第二个 Expression 存在,设 increment 为第二个 Expression;否则,设 incrementempty
  12. bodyResultCompletion(ForBodyEvaluation(test, increment, Statement, perIterationLets, labelSet))。
  13. 运行执行上下文的词法环境设置为 oldEnv
  14. 返回 ? bodyResult

14.7.4.3 ForBodyEvaluation ( test, increment, stmt, perIterationBindings, labelSet )

抽象操作 ForBodyEvaluation 接受参数 test(一个 Expression Parse Nodeempty),increment(一个 Expression Parse Nodeempty),stmt(一个 Statement Parse Node), perIterationBindings(一个 List of Strings),和 labelSet(一个 List of Strings)并返回一个 normal completion containing 一个 ECMAScript language value 或一个 abrupt completion。它在调用时执行以下步骤:

  1. Vundefined
  2. 执行 ? CreatePerIterationEnvironment(perIterationBindings)。
  3. 重复,
    1. 如果 test 不是 empty,则
      1. testRef 为 ? 求值 of test
      2. testValue 为 ? GetValue(testRef)。
      3. 如果 ToBoolean(testValue) 是 false,返回 V
    2. resultCompletion(求值 of stmt)。
    3. 如果 LoopContinues(result, labelSet) 是 false,返回 ? UpdateEmpty(result, V)。
    4. 如果 result.[[Value]] 不是 empty,设 Vresult.[[Value]]
    5. 执行 ? CreatePerIterationEnvironment(perIterationBindings)。
    6. 如果 increment 不是 empty,则
      1. incRef 为 ? 求值 of increment
      2. 执行 ? GetValue(incRef)。

14.7.4.4 CreatePerIterationEnvironment ( perIterationBindings )

抽象操作 CreatePerIterationEnvironment 接受参数 perIterationBindings (一个 List of Strings)并返回一个 normal completion containing unused 或一个 throw completion。它在调用时执行以下步骤:

  1. 如果 perIterationBindings 有任何元素,则
    1. lastIterationEnv运行执行上下文的词法环境。
    2. outerlastIterationEnv.[[OuterEnv]]
    3. 断言outer 不是 null
    4. thisIterationEnvNewDeclarativeEnvironment(outer)。
    5. 对于 perIterationBindings 的每个元素 bn,执行
      1. 执行 ! thisIterationEnv.CreateMutableBinding(bn, false)。
      2. lastValue 为 ? lastIterationEnv.GetBindingValue(bn, true)。
      3. 执行 ! thisIterationEnv.InitializeBinding(bn, lastValue)。
    6. 运行执行上下文的词法环境设置为 thisIterationEnv
  2. 返回 unused

14.7.5 for-infor-offor-await-of 语句

语法

ForInOfStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] LeftHandSideExpression[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( [lookahead ≠ let] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] ForDeclaration[Yield, Await] : LetOrConst ForBinding[?Yield, ?Await] ForBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] 注意

本节由附录 B.3.5 扩展。

14.7.5.1 静态语义:早期错误

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement 注意

只有在实现 B.3.1 中指定的扩展时,才需要应用此规则。

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement

如果 LeftHandSideExpressionObjectLiteralArrayLiteral,则以下早期错误规则适用:

如果 LeftHandSideExpression 既不是 ObjectLiteral 也不是 ArrayLiteral,则以下早期错误规则适用:

ForInOfStatement : for ( ForDeclaration in Expression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement

14.7.5.2 静态语义:IsDestructuring

语法导向操作 IsDestructuring 不接受参数并返回一个布尔值。它在以下产生式上定义:

MemberExpression : PrimaryExpression
  1. 如果 PrimaryExpressionObjectLiteralArrayLiteral, 返回 true
  2. 返回 false
MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression
  1. 返回 false
ForDeclaration : LetOrConst ForBinding
  1. 返回 IsDestructuring of ForBinding
ForBinding : BindingIdentifier
  1. 返回 false
ForBinding : BindingPattern
  1. 返回 true
注意

本节由附录 B.3.5 扩展。

14.7.5.3 运行时语义:ForDeclarationBindingInitialization

语法导向操作 ForDeclarationBindingInitialization 接受参数 value(一个 ECMAScript 语言值)和 environment(一个 环境记录undefined)并返回一个 正常完成包含 unused 或一个 异常完成

注意

undefined 传递给 environment 表示应使用 PutValue 操作来分配初始化值。这适用于 var 语句和某些 非严格函数 的形式参数列表(参见 10.2.11)。 在这些情况下,词法绑定被提升并在评估其初始化器之前预初始化。

它在以下产生式上定义:

ForDeclaration : LetOrConst ForBinding
  1. 返回 ? BindingInitialization of ForBinding with arguments value and environment

14.7.5.4 运行时语义:ForDeclarationBindingInstantiation

语法导向操作 ForDeclarationBindingInstantiation 接受参数 environment(一个 声明性环境记录)并返回 unused。它在以下产生式上定义:

ForDeclaration : LetOrConst ForBinding
  1. 对于 BoundNames of ForBinding 的每个元素 name,执行
    1. 如果 IsConstantDeclaration of LetOrConsttrue,则
      1. 执行 ! environment.CreateImmutableBinding(name, true)。
    2. 否则,
      1. 执行 ! environment.CreateMutableBinding(name, false)。
  2. 返回 unused

14.7.5.5 运行时语义:ForInOfLoopEvaluation

语法导向操作 ForInOfLoopEvaluation 接受参数 labelSet(一个 List of Strings)并返回一个 正常完成包含 一个 ECMAScript 语言值 或一个 异常完成。它在以下产生式上定义:

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement
  1. keyResult 为 ? ForIn/OfHeadEvaluation(« », Expression, enumerate)。
  2. 返回 ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, enumerate, assignment, labelSet)。
ForInOfStatement : for ( var ForBinding in Expression ) Statement
  1. keyResult 为 ? ForIn/OfHeadEvaluation(« », Expression, enumerate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, enumerate, var-binding, labelSet)。
ForInOfStatement : for ( ForDeclaration in Expression ) Statement
  1. keyResult 为 ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, Expression, enumerate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, enumerate, lexical-binding, labelSet)。
ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement
  1. keyResult 为 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet)。
ForInOfStatement : for ( var ForBinding of AssignmentExpression ) Statement
  1. keyResult 为 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, var-binding, labelSet)。
ForInOfStatement : for ( ForDeclaration of AssignmentExpression ) Statement
  1. keyResult 为 ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexical-binding, labelSet)。
ForInOfStatement : for await ( LeftHandSideExpression of AssignmentExpression ) Statement
  1. keyResult 为 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet, async)。
ForInOfStatement : for await ( var ForBinding of AssignmentExpression ) Statement
  1. keyResult 为 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, var-binding, labelSet, async)。
ForInOfStatement : for await ( ForDeclaration of AssignmentExpression ) Statement
  1. keyResult 为 ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, async-iterate)。
  2. 返回 ? ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexical-binding, labelSet, async)。
注意

本节由附录 B.3.5 扩展。

14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind )

抽象操作 ForIn/OfHeadEvaluation 接受参数 uninitializedBoundNames(一个 字符串列表),expr(一个 表达式 解析节点 或一个 赋值表达式 解析节点),以及 iterationKindenumerateiterate,或 async-iterate),并返回一个 正常完成记录 包含一个 迭代器记录 或一个 异常完成记录。它在调用时执行以下步骤:

  1. oldEnv运行执行上下文 的词法环境。
  2. 如果 uninitializedBoundNames 不为空,则
    1. 断言uninitializedBoundNames 没有重复条目。
    2. newEnvNewDeclarativeEnvironment(oldEnv)。
    3. 对于 uninitializedBoundNames 中的每个字符串 name,执行
      1. 执行 ! newEnv.CreateMutableBinding(name, false)。
    4. 运行执行上下文 的词法环境设置为 newEnv
  3. exprRefCompletion(Evaluation of expr)。
  4. 运行执行上下文 的词法环境设置为 oldEnv
  5. exprValue 为 ? GetValue(? exprRef)。
  6. 如果 iterationKindenumerate,则
    1. 如果 exprValueundefinednull,则
      1. 返回 完成记录 { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }。
    2. obj 为 ! ToObject(exprValue)。
    3. iteratorEnumerateObjectProperties(obj)。
    4. nextMethod 为 ! GetV(iterator, "next")。
    5. 返回 迭代器记录 { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }。
  7. 否则
    1. 断言iterationKinditerateasync-iterate
    2. 如果 iterationKindasync-iterate,令 iteratorKindasync
    3. 否则,令 iteratorKindsync
    4. 返回 ? GetIterator(exprValue, iteratorKind)。

14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] )

抽象操作 ForIn/OfBodyEvaluation 接受参数 lhs(一个 解析节点),stmt (一个 语句 解析节点), iteratorRecord(一个 迭代器记录), iterationKindenumerateiterate), lhsKindassignmentvar-binding,或 lexical-binding),以及 labelSet(一个 字符串列表), 以及可选参数 iteratorKindsyncasync),并返回一个 正常完成记录 包含一个 ECMAScript 语言值 或一个 异常完成记录。 它在调用时执行以下步骤:

  1. 如果 iteratorKind 不存在,设置 iteratorKindsync
  2. oldEnv运行执行上下文 的词法环境。
  3. Vundefined
  4. destructuringIsDestructuringlhs
  5. 如果 destructuringtruelhsKindassignment,则
    1. 断言lhs 是一个 LeftHandSideExpression
    2. assignmentPatternAssignmentPattern覆盖lhs
  6. 重复,
    1. nextResult 为 ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]])。
    2. 如果 iteratorKindasync, 设置 nextResult 为 ? Await(nextResult)。
    3. 如果 nextResult 不是一个 Object,抛出一个 TypeError 异常。
    4. done 为 ? IteratorComplete(nextResult)。
    5. 如果 donetrue,返回 V
    6. nextValue 为 ? IteratorValue(nextResult)。
    7. 如果 lhsKindassignmentvar-binding,则
      1. 如果 destructuringtrue, 则
        1. 如果 lhsKindassignment,则
          1. statusCompletion(DestructuringAssignmentEvaluation of assignmentPattern with argument nextValue)。
        2. 否则,
          1. 断言lhsKindvar-binding
          2. 断言lhs 是一个 ForBinding
          3. statusCompletion(BindingInitialization of lhs 使用 参数 nextValueundefined)。
      2. 否则,
        1. lhsRefCompletion(Evaluation of lhs)。(可能会被 多次评估。)
        2. 如果 lhsRef 是一个 异常 完成,则
          1. statuslhsRef
        3. 否则,
          1. statusCompletion(PutValue(lhsRef.[[Value]], nextValue))。
    8. 否则,
      1. 断言lhsKindlexical-binding
      2. 断言lhs 是一个 ForDeclaration
      3. iterationEnvNewDeclarativeEnvironment(oldEnv)。
      4. 执行 ForDeclarationBindingInstantiationlhs 使用参数 iterationEnv
      5. 设置 运行 执行上下文 的词法环境为 iterationEnv
      6. 如果 destructuringtrue, 则
        1. statusCompletion(ForDeclarationBindingInitialization of lhs 使用参数 nextValueiterationEnv)。
      7. 否则,
        1. 断言lhs 绑定一个单一的名称。
        2. lhsNameBoundNameslhs 的唯一元素。
        3. lhsRef 为 ! ResolveBinding(lhsName)。
        4. statusCompletion(InitializeReferencedBinding(lhsRef, nextValue))。
    9. 如果 status 是一个 异常 完成,则
      1. 设置 运行 执行上下文 的词法环境为 oldEnv
      2. 如果 iteratorKindasync,返回 ? AsyncIteratorClose(iteratorRecord, status)。
      3. 如果 iterationKindenumerate,则
        1. 返回 ? status
      4. 否则,
        1. 断言iterationKinditerate
        2. 返回 ? IteratorClose(iteratorRecord, status)。
    10. resultCompletion(Evaluation of stmt)。
    11. 设置 运行 执行上下文 的词法环境为 oldEnv
    12. 如果 LoopContinues(result, labelSet) 是 false,则
      1. 如果 iterationKindenumerate,则
        1. 返回 ? UpdateEmpty(result, V)。
      2. 否则,
        1. 断言iterationKinditerate
        2. 设置 statusCompletion(UpdateEmpty(result, V))。
        3. 如果 iteratorKindasync,返回 ? AsyncIteratorClose(iteratorRecord, status)。
        4. 返回 ? IteratorClose(iteratorRecord, status)。
    13. 如果 result.[[Value]] 不是 empty,设置 Vresult.[[Value]]

14.7.5.8 运行时语义:评估

BindingIdentifier : Identifier yield await
  1. bindingIdStringValueBindingIdentifier
  2. 返回 ? ResolveBinding(bindingId)。

14.7.5.9 EnumerateObjectProperties ( O )

抽象操作 EnumerateObjectProperties 接受参数 O(一个对象)并返回一个迭代器。它在调用时执行以下步骤:

  1. 返回一个迭代器对象(27.1.1.2),其 next 方法遍历 O 的所有可枚举的字符串键属性。迭代器对象对 ECMAScript 代码永远不可直接访问。遍历属性的机制和顺序未指定,但必须符合以下规则。

迭代器的 throwreturn 方法是 null,并且永远不会被调用。迭代器的 next 方法处理对象属性以确定属性键是否应作为迭代器值返回。返回的属性键不包括 Symbols。目标对象的属性可能在枚举期间被删除。在迭代器的 next 方法处理之前删除的属性将被忽略。如果在枚举期间向目标对象添加新属性,则不能保证新添加的属性会在活动枚举中被处理。一个属性名在任何枚举中最多由迭代器的 next 方法返回一次。

枚举目标对象的属性包括枚举其原型及其原型的原型等的属性,递归地;但如果原型的属性与迭代器的 next 方法已经处理的属性同名,则不处理原型的属性。原型对象的可枚举属性名必须通过调用 EnumerateObjectProperties 并将原型对象作为参数来获取。EnumerateObjectProperties 必须通过调用目标对象的 [[OwnPropertyKeys]] 内部方法来获取目标对象的自有属性键。目标对象的属性属性必须通过调用其 [[GetOwnProperty]] 内部方法来获取。

此外,如果 O 或其原型链中的任何对象不是 Proxy 奇特对象TypedArray模块命名空间奇特对象,或实现提供的 奇特对象,则迭代器必须表现得像由 CreateForInIterator(O) 给出的迭代器,直到以下情况之一发生:

  • O 或其原型链中的对象的 [[Prototype]] 内部槽的值发生变化,
  • O 或其原型链中的对象的属性被删除,
  • O 的原型链中的对象的属性被添加,或
  • O 或其原型链中的对象的属性的 [[Enumerable]] 属性发生变化。
注1

ECMAScript 实现不需要直接实现 14.7.5.10.2.1 中的算法。它们可以选择任何实现,只要其行为不会偏离该算法,除非违反了前一段中的约束。

以下是一个符合这些规则的 ECMAScript 生成器函数的非正式定义:

function* EnumerateObjectProperties(obj) {
  const visited = new Set();
  for (const key of Reflect.ownKeys(obj)) {
    if (typeof key === "symbol") continue;
    const desc = Reflect.getOwnPropertyDescriptor(obj, key);
    if (desc) {
      visited.add(key);
      if (desc.enumerable) yield key;
    }
  }
  const proto = Reflect.getPrototypeOf(obj);
  if (proto === null) return;
  for (const protoKey of EnumerateObjectProperties(proto)) {
    if (!visited.has(protoKey)) yield protoKey;
  }
}
注2
实现不需要匹配 CreateForInIterator奇特对象 列表是基于历史实现在这些情况下存在差异,并且在所有其他情况下达成一致。

14.7.5.10 For-In 迭代器对象

For-In 迭代器是表示特定对象上的特定迭代的对象。For-In 迭代器对象永远不会直接对 ECMAScript 代码可访问;它们仅存在于阐明 EnumerateObjectProperties 的行为。

14.7.5.10.1 CreateForInIterator ( object )

抽象操作 CreateForInIterator 接受参数 object(一个对象)并返回一个 For-In 迭代器。它用于创建一个 For-In 迭代器对象,该对象按特定顺序迭代 object 的自身和继承的可枚举字符串属性。调用时执行以下步骤:

  1. iteratorOrdinaryObjectCreate(%ForInIteratorPrototype%, « [[Object]], [[ObjectWasVisited]], [[VisitedKeys]], [[RemainingKeys]] »)。
  2. iterator.[[Object]] 设置为 object
  3. iterator.[[ObjectWasVisited]] 设置为 false
  4. iterator.[[VisitedKeys]] 设置为一个新的空 列表
  5. iterator.[[RemainingKeys]] 设置为一个新的空 列表
  6. 返回 iterator

14.7.5.10.2 %ForInIteratorPrototype% 对象

%ForInIteratorPrototype% 对象:

  • 具有所有 For-In 迭代器对象继承的属性。
  • 是一个 普通对象
  • 有一个内部槽 [[Prototype]],其值是 %IteratorPrototype%
  • 永远不能被 ECMAScript 代码直接访问。
  • 具有以下属性:

14.7.5.10.2.1 %ForInIteratorPrototype%.next ( )

  1. Othis 值。
  2. 断言O 是一个 对象
  3. 断言O 具有 For-In 迭代器实例的所有内部槽 (14.7.5.10.3)。
  4. objectO.[[Object]]
  5. 重复,
    1. 如果 O.[[ObjectWasVisited]]false,则
      1. keys 为 ? object.[[OwnPropertyKeys]]()
      2. keys 的每个元素 key,执行
        1. 如果 key 是一个 字符串,则
          1. key 追加到 O.[[RemainingKeys]]
      3. O.[[ObjectWasVisited]] 设置为 true
    2. 重复,直到 O.[[RemainingKeys]] 为空,
      1. rO.[[RemainingKeys]] 的第一个元素。
      2. O.[[RemainingKeys]] 中移除第一个元素。
      3. 如果 O.[[VisitedKeys]] 中不存在一个元素 v 使得 SameValue(r, v) 为 true,则
        1. desc 为 ? object.[[GetOwnProperty]](r)。
        2. 如果 desc 不为 undefined,则
          1. r 追加到 O.[[VisitedKeys]]
          2. 如果 desc.[[Enumerable]]true,返回 CreateIterResultObject(r, false)。
    3. object 设置为 ? object.[[GetPrototypeOf]]()
    4. O.[[Object]] 设置为 object
    5. O.[[ObjectWasVisited]] 设置为 false
    6. 如果 objectnull,返回 CreateIterResultObject(undefined, true)。

14.7.5.10.3 For-In 迭代器实例的属性

For-In 迭代器实例是 普通对象,它们从 %ForInIteratorPrototype% 内部对象继承属性。For-In 迭代器实例初始创建时具有 表 39 中列出的内部槽。

表 39: For-In 迭代器实例的内部槽
内部槽 类型 描述
[[Object]] 一个对象 正在迭代其属性的对象值。
[[ObjectWasVisited]] 一个布尔值 如果迭代器已经在 [[Object]] 上调用了 [[OwnPropertyKeys]] 则为 true,否则为 false
[[VisitedKeys]] 一个 字符串列表 到目前为止,该迭代器已发出的值。
[[RemainingKeys]] 一个 字符串列表 在迭代其原型的属性(如果其原型不为 null)之前,当前对象剩余要发出的值。

14.8 continue 语句

语法

ContinueStatement [Yield, Await] : continue ; continue [no LineTerminator here] LabelIdentifier [?Yield, ?Await] ;

14.8.1 静态语义:早期错误

ContinueStatement : continue ; continue LabelIdentifier ;

14.8.2 运行时语义:求值

ContinueStatement : continue ;
  1. 返回 完成记录 { [[Type]]: continue, [[Value]]: empty, [[Target]]: empty }.
ContinueStatement : continue LabelIdentifier ;
  1. label StringValue LabelIdentifier
  2. 返回 完成记录 { [[Type]]: continue, [[Value]]: empty, [[Target]]: label }.

14.9 break 语句

语法

BreakStatement [Yield, Await] : break ; break [no LineTerminator here] LabelIdentifier [?Yield, ?Await] ;

14.9.1 静态语义:早期错误

BreakStatement : break ;

14.9.2 运行时语义:求值

BreakStatement : break ;
  1. 返回 完成记录 { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }.
BreakStatement : break LabelIdentifier ;
  1. label StringValue LabelIdentifier
  2. 返回 完成记录 { [[Type]]: break, [[Value]]: empty, [[Target]]: label }.

14.10 return 语句

语法

ReturnStatement [Yield, Await] : return ; return [no LineTerminator here] Expression [+In, ?Yield, ?Await] ; Note

return 语句会导致函数停止执行,并在大多数情况下返回一个值给调用者。如果省略了 Expression ,返回值为 undefined。否则,返回值是 Expression 的值。根据周围的上下文,return 语句可能实际上不会返回值给调用者。例如,在 try 块中,return 语句的 Completion Record 可能在执行 finally 块时被另一个 Completion Record 替换。

14.10.1 运行时语义:求值

ReturnStatement : return ;
  1. 返回 Completion Record { [[Type]]: return, [[Value]]: undefined, [[Target]]: empty }.
ReturnStatement : return Expression ;
  1. exprRef 为 ?  Evaluation Expression
  2. exprValue 为 ?  GetValue (exprRef)。
  3. 如果 GetGeneratorKind () 是 async,设置 exprValue 为 ?  Await (exprValue)。
  4. 返回 Completion Record { [[Type]]: return, [[Value]]: exprValue, [[Target]]: empty }.

14.11 with 语句

注 1

在新的 ECMAScript 代码中,不鼓励使用 Legacy with 语句。考虑使用在 严格模式代码 非严格模式代码 中都允许的替代方案,如 解构赋值

语法

WithStatement [Yield, Await, Return] : with ( Expression [+In, ?Yield, ?Await] ) Statement [?Yield, ?Await, ?Return] 注 2

with 语句为计算对象添加了一个 对象环境记录 到当前执行上下文的词法环境中。然后使用这个扩展的词法环境执行一个语句。最后,它恢复原始的词法环境。

14.11.1 静态语义:早期错误

WithStatement : with ( Expression ) Statement

仅在实现 B.3.1 中指定的扩展时,才需要应用第二条规则。

14.11.2 运行时语义:求值

WithStatement : with ( Expression ) Statement
  1. val 为 ?  Evaluation Expression
  2. obj 为 ?  ToObject (? GetValue (val))。
  3. oldEnv 为当前执行上下文的 词法环境
  4. newEnv NewObjectEnvironment (obj, true, oldEnv)。
  5. 将当前执行上下文的 词法环境 设置为 newEnv
  6. C Completion ( Evaluation Statement )。
  7. 将当前执行上下文的 词法环境 设置回 oldEnv
  8. 返回 ?  UpdateEmpty (C, undefined)。

无论以何种方式退出嵌入的 Statement ,无论是正常还是以某种形式的 中止完成 或异常,词法环境总是恢复到原来的状态。

14.12 switch 语句

语法

SwitchStatement [Yield, Await, Return] : switch ( Expression [+In, ?Yield, ?Await] ) CaseBlock [?Yield, ?Await, ?Return] CaseBlock [Yield, Await, Return] : { CaseClauses [?Yield, ?Await, ?Return] opt } { CaseClauses [?Yield, ?Await, ?Return] opt DefaultClause [?Yield, ?Await, ?Return] CaseClauses [?Yield, ?Await, ?Return] opt } CaseClauses [Yield, Await, Return] : CaseClause [?Yield, ?Await, ?Return] CaseClauses [?Yield, ?Await, ?Return] CaseClause [?Yield, ?Await, ?Return] CaseClause [Yield, Await, Return] : case Expression [+In, ?Yield, ?Await] : StatementList [?Yield, ?Return] opt DefaultClause [Yield, Await, Return] : default : StatementList [?Yield, ?Return] opt

14.12.1 静态语义:早期错误

SwitchStatement : switch ( Expression ) CaseBlock

14.12.2 运行时语义:CaseBlockEvaluation

语法定向操作 CaseBlockEvaluation 接受参数 input (一个 ECMAScript 语言值 ),并返回 正常完成包含的 ECMAScript 语言值 中止完成 。它在以下产生式上分段定义:

CaseBlock : { }
  1. 返回 undefined
CaseBlock : { CaseClauses }
  1. Vundefined
  2. A List 中的 CaseClause 项,按源文本顺序排列。
  3. foundfalse
  4. A 中的每个 CaseClause C,执行以下操作:
    1. 如果 foundfalse,则:
      1. found 为 ? CaseClauseIsSelected (C, input)。
    2. 如果 foundtrue,则:
      1. R Completion ( Evaluation (C))。
      2. 如果 R.[[Value]] 不是 empty,则将 V 设为 R.[[Value]]
      3. 如果 R 中止完成 ,则返回 ? UpdateEmpty (R, V)。
  5. 返回 V
CaseBlock : { CaseClauses opt DefaultClause CaseClauses opt }
  1. Vundefined
  2. 如果存在第一个 CaseClauses ,则:
    1. A List 中的 CaseClause 项,按源文本顺序排列。
  3. 否则:
    1. A 为一个新的空 List
  4. foundfalse
  5. A 中的每个 CaseClause C,执行以下操作:
    1. 如果 foundfalse,则:
      1. found 为 ? CaseClauseIsSelected (C, input)。
    2. 如果 foundtrue,则:
      1. R Completion ( Evaluation (C))。
      2. 如果 R.[[Value]] 不是 empty,则将 V 设为 R.[[Value]]
      3. 如果 R 中止完成 ,则返回 ? UpdateEmpty (R, V)。
  6. foundInBfalse
  7. 如果存在第二个 CaseClauses ,则:
    1. B List 中的 CaseClause 项,按源文本顺序排列。
  8. 否则:
    1. B 为一个新的空 List
  9. 如果 foundfalse,则:
    1. B 中的每个 CaseClause C,执行以下操作:
      1. 如果 foundInBfalse,则:
        1. foundInB 为 ? CaseClauseIsSelected (C, input)。
      2. 如果 foundInBtrue,则:
        1. R Completion ( Evaluation ( CaseClause C))。
        2. 如果 R.[[Value]] 不是 empty,则将 V 设为 R.[[Value]]
        3. 如果 R 中止完成 ,则返回 ? UpdateEmpty (R, V)。
  10. 如果 foundInBtrue,则返回 V
  11. defaultR Completion ( Evaluation ( DefaultClause ))。
  12. 如果 defaultR.[[Value]] 不是 empty,则将 V 设为 defaultR.[[Value]]
  13. 如果 defaultR 中止完成 ,则返回 ? UpdateEmpty (defaultR, V)。
  14. 注:以下是第二个 CaseClauses 的另一个完整迭代。
  15. B 中的每个 CaseClause C,执行以下操作:
    1. R Completion ( Evaluation ( CaseClause C))。
    2. 如果 R.[[Value]] 不是 empty,则将 V 设为 R.[[Value]]
    3. 如果 R 中止完成 ,则返回 ? UpdateEmpty (R, V)。
  16. 返回 V

14.12.3 CaseClauseIsSelected ( C, input )

抽象操作 CaseClauseIsSelected 接受参数 C(一个 CaseClause 解析节点 )和 input(一个 ECMAScript 语言值 ),并返回 正常完成包含的 布尔值或 中止完成 。它在调用时执行以下步骤:

  1. 断言 C CaseClause : case Expression : StatementList opt 的一个实例。
  2. exprRef 为 ? Evaluation C Expression
  3. clauseSelector 为 ? GetValue (exprRef)。
  4. 返回 IsStrictlyEqual (input, clauseSelector)。

此操作不执行 C StatementList (如果有)。 CaseBlock 算法使用其返回值来确定要开始执行的 StatementList

14.12.4 运行时语义:Evaluation

SwitchStatement : switch ( Expression ) CaseBlock
  1. exprRef 为 ? Evaluation ( Expression )。
  2. switchValue 为 ? GetValue (exprRef)。
  3. oldEnv 当前执行上下文 的 LexicalEnvironment。
  4. blockEnv NewDeclarativeEnvironment (oldEnv)。
  5. 执行 BlockDeclarationInstantiation ( CaseBlock , blockEnv)。
  6. 当前执行上下文 的 LexicalEnvironment 设置为 blockEnv
  7. R Completion ( CaseBlockEvaluation ( CaseBlock , switchValue))。
  8. 当前执行上下文 的 LexicalEnvironment 设置回 oldEnv
  9. 返回 R

无论控制如何离开 SwitchStatement ,LexicalEnvironment 总是恢复到其先前状态。

CaseClause : case Expression :
  1. 返回 empty
CaseClause : case Expression : StatementList
  1. 返回 ? Evaluation ( StatementList )。
DefaultClause : default :
  1. 返回 empty
DefaultClause : default : StatementList
  1. 返回 ? Evaluation ( StatementList )。

14.13 带标签的语句

语法

LabelledStatement [Yield, Await, Return] : LabelIdentifier [?Yield, ?Await] : LabelledItem [?Yield, ?Await, ?Return] LabelledItem [Yield, Await, Return] : Statement [?Yield, ?Await, ?Return] FunctionDeclaration [?Yield, ?Await, ~Default] 注释

一个 Statement 可能被一个标签前缀。带标签的语句仅与带标签的breakcontinue语句结合使用。ECMAScript 没有goto语句。 一个 Statement 可以是 LabelledStatement 的一部分,而后者本身可以是 LabelledStatement 的一部分,依此类推。以这种方式引入的标签在描述单个语句的语义时统称为“当前标签集”。

14.13.1 静态语义:早期错误

LabelledItem : FunctionDeclaration
  • 如果此生成的源文本匹配任何源文本,则为语法错误。
注释

如果实现了 B.3.1 中指定的扩展,则此规则的替代定义是必要的。

14.13.2 静态语义:IsLabelledFunction (stmt)

抽象操作 IsLabelledFunction 接受参数 stmt (一个 Statement 解析节点 ) 并返回一个布尔值。当调用时执行以下步骤:

  1. 如果 stmt 不是一个 LabelledStatement ,返回 false
  2. item 成为 stmt LabelledItem
  3. 如果 item LabelledItem : FunctionDeclaration ,返回 true
  4. subStmt 成为 item Statement
  5. 返回 IsLabelledFunction (subStmt)。

14.13.3 运行时语义:评估

LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回 ?  LabelledEvaluation 的这个 LabelledStatement ,参数为 « »。

14.13.4 运行时语义:LabelledEvaluation

语法指向操作 LabelledEvaluation 接受参数 labelSet(一个 列表 字符串)并返回一个 正常完成包含 ECMAScript 语言值 或一个 突然完成 。它在以下生成中逐步定义:

BreakableStatement : IterationStatement
  1. stmtResult 成为 Completion ( LoopEvaluation IterationStatement ,参数为 labelSet)。
  2. 如果 stmtResult 是一个 break completion ,则
    1. 如果 stmtResult.[[Target]]empty,则
      1. 如果 stmtResult.[[Value]]empty,则将 stmtResult 设置为 NormalCompletion (undefined)。
      2. 否则,将 stmtResult 设置为 NormalCompletion (stmtResult.[[Value]])。
  3. 返回 ? stmtResult
BreakableStatement : SwitchStatement
  1. stmtResult 成为 Completion ( Evaluation SwitchStatement )。
  2. 如果 stmtResult 是一个 break completion ,则
    1. 如果 stmtResult.[[Target]]empty,则
      1. 如果 stmtResult.[[Value]]empty,则将 stmtResult 设置为 NormalCompletion (undefined)。
      2. 否则,将 stmtResult 设置为 NormalCompletion (stmtResult.[[Value]])。
  3. 返回 ? stmtResult
注释 1

一个 BreakableStatement 是可以通过无标签的 BreakStatement 退出的语句。

LabelledStatement : LabelIdentifier : LabelledItem
  1. label 成为 StringValue LabelIdentifier
  2. newLabelSet 成为 列表连接 labelSet 和 « label »。
  3. stmtResult 成为 Completion ( LabelledEvaluation LabelledItem ,参数为 newLabelSet)。
  4. 如果 stmtResult 是一个 break completion 并且 stmtResult.[[Target]]label,则
    1. stmtResult 设置为 NormalCompletion (stmtResult.[[Value]])。
  5. 返回 ? stmtResult
LabelledItem : FunctionDeclaration
  1. 返回 ?  Evaluation FunctionDeclaration
Statement : BlockStatement VariableStatement EmptyStatement ExpressionStatement IfStatement ContinueStatement BreakStatement ReturnStatement WithStatement ThrowStatement TryStatement DebuggerStatement
  1. 返回 ?  Evaluation Statement
注释 2

Statement 的唯一两个在 LabelledEvaluation 中具有特殊语义的生成是 BreakableStatement LabelledStatement

14.14 throw 语句

语法

ThrowStatement [Yield, Await] : throw [此处不能有 行终止符 ] 表达式 [+In, ?Yield, ?Await] ;

14.14.1 运行时语义:求值

ThrowStatement : throw 表达式 ;
  1. exprRef 为 ?  Evaluation 表达式
  2. exprValue 为 ?  GetValue (exprRef)。
  3. 返回 ThrowCompletion (exprValue)。

14.15 try 语句

语法

TryStatement [Yield, Await, Return] : try Block [?Yield, ?Await, ?Return] Catch [?Yield, ?Await, ?Return] try Block [?Yield, ?Await, ?Return] Finally [?Yield, ?Await, ?Return] try Block [?Yield, ?Await, ?Return] Catch [?Yield, ?Await, ?Return] Finally [?Yield, ?Await, ?Return] Catch [Yield, Await, Return] : catch ( CatchParameter [?Yield, ?Await] ) Block [?Yield, ?Await, ?Return] catch Block [?Yield, ?Await, ?Return] Finally [Yield, Await, Return] : finally Block [?Yield, ?Await, ?Return] CatchParameter [Yield, Await] : BindingIdentifier [?Yield, ?Await] BindingPattern [?Yield, ?Await] 注意

try 语句包含可能发生异常的代码块,如运行时错误或 throw 语句。catch 子句提供异常处理代码。当 catch 子句捕获异常时,其 CatchParameter 绑定到该异常。

14.15.1 静态语义:早期错误

Catch : catch ( CatchParameter ) Block 注意

对于此生成规则的替代静态语义定义,见 B.3.4

14.15.2 运行时语义:CatchClauseEvaluation

CatchClauseEvaluation 是一个带有参数 thrownValue(一个 ECMAScript 语言值)的语法直接操作,返回一个包含 ECMAScript 语言值的正常完成记录或一个中断完成记录。它在以下生成规则中定义:

Catch : catch ( CatchParameter ) Block
  1. oldEnv 为当前执行上下文的 LexicalEnvironment。
  2. catchEnv NewDeclarativeEnvironment (oldEnv)。
  3. 对于 BoundNames CatchParameter 中的每个元素 argName,执行
    1. 执行 ! catchEnv.CreateMutableBinding(argName, false)。
  4. 将当前执行上下文的 LexicalEnvironment 设置为 catchEnv
  5. status Completion ( BindingInitialization CatchParameter ,参数为 thrownValuecatchEnv)。
  6. 如果 status 是一个中断完成,则
    1. 将当前执行上下文的 LexicalEnvironment 设置为 oldEnv
    2. 返回 ? status
  7. B Completion ( Evaluation Block )。
  8. 将当前执行上下文的 LexicalEnvironment 设置为 oldEnv
  9. 返回 ? B
Catch : catch Block
  1. 返回 ?  Evaluation Block
注意

无论控制如何离开 Block ,LexicalEnvironment 总是恢复到原来的状态。

14.15.3 运行时语义:Evaluation

TryStatement : try Block Catch
  1. B Completion ( Evaluation Block )。
  2. 如果 B 是一个 throw completion ,令 C Completion ( CatchClauseEvaluation Catch ,参数为 B.[[Value]])。
  3. 否则,令 CB
  4. 返回 ?  UpdateEmpty (C, undefined)。
TryStatement : try Block Finally
  1. B Completion ( Evaluation Block )。
  2. F Completion ( Evaluation Finally )。
  3. 如果 F 是一个 normal completion ,则将 F 设置为 B
  4. 返回 ?  UpdateEmpty (F, undefined)。
TryStatement : try Block Catch Finally
  1. B Completion ( Evaluation Block )。
  2. 如果 B 是一个 throw completion ,令 C Completion ( CatchClauseEvaluation Catch ,参数为 B.[[Value]])。
  3. 否则,令 CB
  4. F Completion ( Evaluation Finally )。
  5. 如果 F 是一个 normal completion ,则将 F 设置为 C
  6. 返回 ?  UpdateEmpty (F, undefined)。

14.16 debugger 语句

句法

DebuggerStatement : debugger ;

14.16.1 运行时语义:Evaluation

注意

执行 DebuggerStatement 时,在调试器下运行时可能会触发断点。如果调试器不存在或未激活,此语句不会产生可观察到的效果。

DebuggerStatement : debugger ;
  1. 如果一个 实现定义 的调试设施可用且已启用,则
    1. 执行一个 实现定义 的调试动作。
    2. 返回一个新的 实现定义 Completion Record
  2. 否则,
    1. 返回 empty

15 ECMAScript 语言:函数和类

注意

各种 ECMAScript 语言元素会导致创建 ECMAScript 函数对象 ( 10.2 )。此类函数的 Evaluation 从执行其 [[Call]] 内部方法开始 ( 10.2.1 )。

15.1 参数列表

语法

UniqueFormalParameters[Yield, Await] : FormalParameters[?Yield, ?Await] FormalParameters[Yield, Await] : [empty] FunctionRestParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameterList[?Yield, ?Await] , FunctionRestParameter[?Yield, ?Await] FormalParameterList[Yield, Await] : FormalParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameter[?Yield, ?Await] FunctionRestParameter[Yield, Await] : BindingRestElement[?Yield, ?Await] FormalParameter[Yield, Await] : BindingElement[?Yield, ?Await]

15.1.1 静态语义:早期错误

UniqueFormalParameters : FormalParameters FormalParameters : FormalParameterList 注意

FormalParameterList 中的同一 BindingIdentifier 的多次出现仅适用于具有简单参数列表且未在 严格模式代码 中定义的函数。

15.1.2 静态语义:ContainsExpression

语法导向操作 ContainsExpression 不接受参数并返回一个布尔值。它分段定义在以下产生式上:

ObjectBindingPattern : { } { BindingRestProperty }
  1. 返回 false
ObjectBindingPattern : { BindingPropertyList , BindingRestProperty }
  1. 返回 ContainsExpressionBindingPropertyList
ArrayBindingPattern : [ Elisionopt ]
  1. 返回 false
ArrayBindingPattern : [ Elisionopt BindingRestElement ]
  1. 返回 ContainsExpressionBindingRestElement
ArrayBindingPattern : [ BindingElementList , Elisionopt ]
  1. 返回 ContainsExpressionBindingElementList
ArrayBindingPattern : [ BindingElementList , Elisionopt BindingRestElement ]
  1. hasContainsExpressionBindingElementList
  2. 如果 hastrue,则返回 true
  3. 返回 ContainsExpressionBindingRestElement
BindingPropertyList : BindingPropertyList , BindingProperty
  1. hasContainsExpressionBindingPropertyList
  2. 如果 hastrue,则返回 true
  3. 返回 ContainsExpressionBindingProperty
BindingElementList : BindingElementList , BindingElisionElement
  1. hasContainsExpressionBindingElementList
  2. 如果 hastrue,则返回 true
  3. 返回 ContainsExpressionBindingElisionElement
BindingElisionElement : Elisionopt BindingElement
  1. 返回 ContainsExpressionBindingElement
BindingProperty : PropertyName : BindingElement
  1. hasIsComputedPropertyKeyPropertyName
  2. 如果 hastrue,则返回 true
  3. 返回 ContainsExpressionBindingElement
BindingElement : BindingPattern Initializer
  1. 返回 true
SingleNameBinding : BindingIdentifier
  1. 返回 false
SingleNameBinding : BindingIdentifier Initializer
  1. 返回 true
BindingRestElement : ... BindingIdentifier
  1. 返回 false
BindingRestElement : ... BindingPattern
  1. 返回 ContainsExpressionBindingPattern
FormalParameters : [empty]
  1. 返回 false
FormalParameters : FormalParameterList , FunctionRestParameter
  1. 如果 ContainsExpressionFormalParameterListtrue,则返回 true
  2. 返回 ContainsExpressionFunctionRestParameter
FormalParameterList : FormalParameterList , FormalParameter
  1. 如果 ContainsExpressionFormalParameterListtrue,则返回 true
  2. 返回 ContainsExpressionFormalParameter
ArrowParameters : BindingIdentifier
  1. 返回 false
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsArrowFormalParameters,它被 涵盖CoverParenthesizedExpressionAndArrowParameterList
  2. 返回 ContainsExpressionformals
AsyncArrowBindingIdentifier : BindingIdentifier
  1. 返回 false

15.1.3 静态语义:IsSimpleParameterList

语法导向操作 IsSimpleParameterList 不接受参数并返回一个布尔值。它分段定义在以下产生式上:

BindingElement : BindingPattern
  1. 返回 false
BindingElement : BindingPattern Initializer
  1. 返回 false
SingleNameBinding : BindingIdentifier
  1. 返回 true
SingleNameBinding : BindingIdentifier Initializer
  1. 返回 false
FormalParameters : [empty]
  1. 返回 true
FormalParameters : FunctionRestParameter
  1. 返回 false
FormalParameters : FormalParameterList , FunctionRestParameter
  1. 返回 false
FormalParameterList : FormalParameterList , FormalParameter
  1. 如果 IsSimpleParameterListFormalParameterListfalse,则返回 false
  2. 返回 IsSimpleParameterListFormalParameter
FormalParameter : BindingElement
  1. 返回 IsSimpleParameterListBindingElement
ArrowParameters : BindingIdentifier
  1. 返回 true
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsArrowFormalParameters,它被 涵盖CoverParenthesizedExpressionAndArrowParameterList
  2. 返回 IsSimpleParameterListformals
AsyncArrowBindingIdentifier : BindingIdentifier
  1. 返回 true
CoverCallExpressionAndAsyncArrowHead : MemberExpression Arguments
  1. headAsyncArrowHead,它被 涵盖CoverCallExpressionAndAsyncArrowHead
  2. 返回 IsSimpleParameterListhead

15.1.4 静态语义:HasInitializer

语法导向操作 HasInitializer 不接受参数并返回一个布尔值。它分段定义在以下产生式上:

BindingElement : BindingPattern
  1. 返回 false
BindingElement : BindingPattern Initializer
  1. 返回 true
SingleNameBinding : BindingIdentifier
  1. 返回 false
SingleNameBinding : BindingIdentifier Initializer
  1. 返回 true
FormalParameterList : FormalParameterList , FormalParameter
  1. 如果 HasInitializerFormalParameterListtrue,则返回 true
  2. 返回 HasInitializerFormalParameter

15.1.5 静态语义:ExpectedArgumentCount

语法导向操作 ExpectedArgumentCount 不接受参数并返回一个 整数。它分段定义在以下产生式上:

FormalParameters : [empty] FunctionRestParameter
  1. 返回 0。
FormalParameters : FormalParameterList , FunctionRestParameter
  1. 返回 ExpectedArgumentCountFormalParameterList
注意

FormalParameterList 的 ExpectedArgumentCount 是 FormalParameters 中在 rest 参数或第一个带初始化器的 FormalParameter 左边的参数数量。 FormalParameter 没有初始化器允许在第一个带初始化器的参数之后,但这些参数被认为是可选的,并且其默认值为 undefined

FormalParameterList : FormalParameter
  1. 如果 HasInitializerFormalParametertrue,返回 0。
  2. 返回 1。
FormalParameterList : FormalParameterList , FormalParameter
  1. countExpectedArgumentCountFormalParameterList
  2. 如果 HasInitializerFormalParameterListtrue 或者 HasInitializerFormalParametertrue,则返回 count
  3. 返回 count + 1。
ArrowParameters : BindingIdentifier
  1. 返回 1。
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsArrowFormalParameters,它被 涵盖CoverParenthesizedExpressionAndArrowParameterList
  2. 返回 ExpectedArgumentCountformals
PropertySetParameterList : FormalParameter
  1. 如果 HasInitializerFormalParametertrue,返回 0。
  2. 返回 1。
AsyncArrowBindingIdentifier : BindingIdentifier
  1. 返回 1。

15.2 函数定义

语法

FunctionDeclaration [Yield, Await, Default] : function BindingIdentifier [?Yield, ?Await] ( FormalParameters [~Yield, ~Await] ) { FunctionBody [~Yield, ~Await] } [+Default] function ( FormalParameters [~Yield, ~Await] ) { FunctionBody [~Yield, ~Await] } FunctionExpression : function BindingIdentifier [~Yield, ~Await] opt ( FormalParameters [~Yield, ~Await] ) { FunctionBody [~Yield, ~Await] } FunctionBody [Yield, Await] : FunctionStatementList [?Yield, ?Await] FunctionStatementList [Yield, Await] : StatementList [?Yield, ?Await, +Return] opt

15.2.1 静态语义:早期错误

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } FunctionExpression : function BindingIdentifier opt ( FormalParameters ) { FunctionBody } 注意

LexicallyDeclaredNames 不包括使用 var 或函数声明绑定的标识符。

FunctionBody : FunctionStatementList

15.2.2 静态语义:FunctionBodyContainsUseStrict

syntax-directed operation FunctionBodyContainsUseStrict 不接受参数并返回一个布尔值。其定义如下:

FunctionBody : FunctionStatementList
  1. 如果 Directive Prologue FunctionBody 包含 Use Strict Directive ,则返回 true;否则,返回 false

15.2.3 运行时语义:EvaluateFunctionBody

syntax-directed operation EvaluateFunctionBody 接受参数 functionObject(一个 ECMAScript function object )和 argumentsList(一个 List )并返回一个 normal completion containing 一个 ECMAScript language value 或一个 abrupt completion 。其定义如下:

FunctionBody : FunctionStatementList
  1. 执行 ?  FunctionDeclarationInstantiation (functionObject, argumentsList)。
  2. 返回 ?  Evaluation FunctionStatementList

15.2.4 运行时语义:InstantiateOrdinaryFunctionObject

syntax-directed operation InstantiateOrdinaryFunctionObject 接受参数 env(一个 Environment Record )和 privateEnv(一个 PrivateEnvironment Record null)并返回一个 ECMAScript function object 。其定义如下:

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. name StringValue BindingIdentifier
  2. sourceText source text matched by FunctionDeclaration
  3. F OrdinaryFunctionCreate ( %Function.prototype% sourceText FormalParameters FunctionBody non-lexical-thisenvprivateEnv)。
  4. 执行 SetFunctionName (Fname)。
  5. 执行 MakeConstructor (F)。
  6. 返回 F
FunctionDeclaration : function ( FormalParameters ) { FunctionBody }
  1. sourceText source text matched by FunctionDeclaration
  2. F OrdinaryFunctionCreate ( %Function.prototype% sourceText FormalParameters FunctionBody non-lexical-thisenvprivateEnv)。
  3. 执行 SetFunctionName (F"default")。
  4. 执行 MakeConstructor (F)。
  5. 返回 F
注意

匿名的 FunctionDeclaration 只能作为 export default 声明的一部分出现,因此其函数代码始终是 strict mode code

15.2.5 运行时语义:InstantiateOrdinaryFunctionExpression

syntax-directed operation InstantiateOrdinaryFunctionExpression 接受可选参数 name(一个 property key 或一个 Private Name )并返回一个 ECMAScript function object 。其定义如下:

FunctionExpression : function ( FormalParameters ) { FunctionBody }
  1. 如果 name 不存在,则将 name 设置为空字符串。
  2. env 为当前执行上下文的词法环境。
  3. privateEnv 为当前执行上下文的私有环境。
  4. sourceText source text matched by FunctionExpression
  5. closure OrdinaryFunctionCreate ( %Function.prototype% sourceText FormalParameters FunctionBody non-lexical-thisenvprivateEnv)。
  6. 执行 SetFunctionName (closurename)。
  7. 执行 MakeConstructor (closure)。
  8. 返回 closure
FunctionExpression : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. 断言 name 不存在。
  2. 设置 name StringValue BindingIdentifier
  3. outerEnv 为当前执行上下文的词法环境。
  4. funcEnv NewDeclarativeEnvironment (outerEnv)。
  5. 执行 ! funcEnv.CreateImmutableBinding(name, false)。
  6. privateEnv 为当前执行上下文的私有环境。
  7. sourceText source text matched by FunctionExpression
  8. closure OrdinaryFunctionCreate ( %Function.prototype% sourceText FormalParameters FunctionBody non-lexical-thisfuncEnvprivateEnv)。
  9. 执行 SetFunctionName (closurename)。
  10. 执行 MakeConstructor (closure)。
  11. 执行 ! funcEnv.InitializeBinding(name, closure)。
  12. 返回 closure
注意

BindingIdentifier 可以在 FunctionExpression FunctionBody 内部被引用,以允许函数递归调用自身。然而,与 FunctionDeclaration 不同, BindingIdentifier 不能从函数表达式的外部引用,也不会影响包围 FunctionExpression 的范围。

15.2.6 运行时语义:Evaluation

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. 返回 empty
注意 1

替代语义见 B.3.2

FunctionDeclaration : function ( FormalParameters ) { FunctionBody }
  1. 返回 empty
FunctionExpression : function BindingIdentifier opt ( FormalParameters ) { FunctionBody }
  1. 返回 InstantiateOrdinaryFunctionExpression FunctionExpression
注意 2

使用 FunctionDeclaration FunctionExpression 定义的每个函数会自动创建一个 "prototype" 属性,以便函数可以作为 constructor 使用。

FunctionStatementList : [empty]
  1. 返回 undefined

15.3 箭头函数定义

语法

ArrowFunction [In, Yield, Await] : ArrowParameters [?Yield, ?Await] [no LineTerminator here] => ConciseBody [?In] ArrowParameters [Yield, Await] : BindingIdentifier [?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList [?Yield, ?Await] ConciseBody [In] : [lookahead ≠ {] ExpressionBody [?In, ~Await] { FunctionBody [~Yield, ~Await] } ExpressionBody [In, Await] : AssignmentExpression [?In, ~Yield, ?Await]

补充语法

处理生产式的实例时
ArrowParameters [Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList [?Yield, ?Await]
CoverParenthesizedExpressionAndArrowParameterList 的解释使用以下语法进行细化:

ArrowFormalParameters [Yield, Await] : ( UniqueFormalParameters [?Yield, ?Await] )

15.3.1 静态语义:早期错误

ArrowFunction : ArrowParameters => ConciseBody ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList

15.3.2 静态语义:ConciseBodyContainsUseStrict

syntax-directed operation ConciseBodyContainsUseStrict 不接受参数并返回一个布尔值。其定义如下:

ConciseBody : ExpressionBody
  1. 返回 false
ConciseBody : { FunctionBody }
  1. 返回 FunctionBodyContainsUseStrict FunctionBody

15.3.3 运行时语义:EvaluateConciseBody

syntax-directed operation EvaluateConciseBody 接受参数 functionObject(一个 ECMAScript 函数对象 )和 argumentsList(一个 列表 ,包含 ECMAScript 语言值 )并返回一个 完成记录 ,其中包含一个 ECMAScript 语言值 或一个 异常完成 。其定义如下:

ConciseBody : ExpressionBody
  1. 执行 ?  FunctionDeclarationInstantiation (functionObjectargumentsList)。
  2. 返回 ?  Evaluation ExpressionBody

15.3.4 运行时语义:InstantiateArrowFunctionExpression

syntax-directed operation InstantiateArrowFunctionExpression 接受可选参数 name(一个 属性键 或一个 私有名称 )并返回一个 ECMAScript 函数对象 。其定义如下:

ArrowFunction : ArrowParameters => ConciseBody
  1. 如果 name 不存在,将 name 设置为 ""
  2. env 为当前执行上下文的词法环境。
  3. privateEnv 为当前执行上下文的私有环境。
  4. sourceText source text matched by ArrowFunction
  5. closure OrdinaryFunctionCreate ( %Function.prototype% sourceText ArrowParameters ConciseBody lexical-thisenvprivateEnv)。
  6. 执行 SetFunctionName (closurename)。
  7. 返回 closure
注意

ArrowFunction 不定义 argumentssuperthisnew.target 的本地绑定。在 ArrowFunction 内对 argumentssuperthisnew.target 的任何引用必须解析为词法上封闭的环境中的绑定。通常,这将是紧密封闭函数的函数环境。即使 ArrowFunction 可能包含对 super 的引用,在步骤 5 中创建的 函数对象 不会通过执行 MakeMethod 变成一个方法。一个引用 super ArrowFunction 总是包含在一个非 ArrowFunction 中,实现 super 所需的状态可以通过 函数对象 所捕获的 env 访问 ArrowFunction

15.3.5 运行时语义:Evaluation

ArrowFunction : ArrowParameters => ConciseBody
  1. 返回 InstantiateArrowFunctionExpression ArrowFunction
ExpressionBody : AssignmentExpression
  1. exprRef 为 ?  Evaluation AssignmentExpression
  2. exprValue 为 ?  GetValue (exprRef)。
  3. 返回 Completion Record { [[Type]]: return[[Value]]exprValue[[Target]]empty }。

15.4 方法定义

语法

MethodDefinition [Yield, Await] : ClassElementName [?Yield, ?Await] ( UniqueFormalParameters [~Yield, ~Await] ) { FunctionBody [~Yield, ~Await] } GeneratorMethod [?Yield, ?Await] AsyncMethod [?Yield, ?Await] AsyncGeneratorMethod [?Yield, ?Await] get ClassElementName [?Yield, ?Await] ( ) { FunctionBody [~Yield, ~Await] } set ClassElementName [?Yield, ?Await] ( PropertySetParameterList ) { FunctionBody [~Yield, ~Await] } PropertySetParameterList : FormalParameter [~Yield, ~Await]

15.4.1 静态语义:早期错误

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }

15.4.2 静态语义:HasDirectSuper

语法指向操作 HasDirectSuper 不接受任何参数并返回一个布尔值。它在以下生成式上逐段定义:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. 如果 UniqueFormalParameters 包含 SuperCall true,则返回 true
  2. 返回 FunctionBody 包含 SuperCall
MethodDefinition : get ClassElementName ( ) { FunctionBody }
  1. 返回 FunctionBody 包含 SuperCall
MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. 如果 PropertySetParameterList 包含 SuperCall true,则返回 true
  2. 返回 FunctionBody 包含 SuperCall
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. 如果 UniqueFormalParameters 包含 SuperCall true,则返回 true
  2. 返回 GeneratorBody 包含 SuperCall
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. 如果 UniqueFormalParameters 包含 SuperCall true,则返回 true
  2. 返回 AsyncGeneratorBody 包含 SuperCall
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. 如果 UniqueFormalParameters 包含 SuperCall true,则返回 true
  2. 返回 AsyncFunctionBody 包含 SuperCall

15.4.3 静态语义:SpecialMethod

语法指向操作 SpecialMethod 不接受任何参数并返回一个布尔值。它在以下生成式上逐段定义:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. 返回 false
MethodDefinition : GeneratorMethod AsyncMethod AsyncGeneratorMethod get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. 返回 true

15.4.4 运行时语义:DefineMethod

语法指向操作 DefineMethod 接受参数 object(一个对象)和可选参数 functionPrototype(一个对象),并返回一个包含字段 [[Key]](一个属性键)和 [[Closure]](一个 ECMAScript 函数对象)的 Record 的正常完成,或一个中断完成。它在以下生成式上逐段定义:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. 令 propKey 为 ?  Evaluation ClassElementName 的结果。
  2. 令 env 为 当前执行上下文 的 LexicalEnvironment。
  3. 令 privateEnv 为 当前执行上下文 的 PrivateEnvironment。
  4. 如果 functionPrototype 存在,则:
    1. 令 prototype 为 functionPrototype。
  5. 否则:
    1. 令 prototype 为 %Function.prototype%
  6. 令 sourceText 为 MethodDefinition 匹配的源文本。
  7. 令 closure 为 OrdinaryFunctionCreate (prototype, sourceText, UniqueFormalParameters , FunctionBody , non-lexical-this, env, privateEnv)。
  8. 执行 MakeMethod (closure, object)。
  9. 返回 { [[Key]]: propKey, [[Closure]]: closure } 的 Record。

15.4.5 运行时语义:MethodDefinitionEvaluation

语法指向操作 MethodDefinitionEvaluation 接受参数 object(一个对象)和 enumerable(一个布尔值),并返回包含一个 PrivateElement 或 unused 的正常完成,或一个中断完成。它在以下生成式上逐段定义:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. 令 methodDef 为 ?  DefineMethod 的结果。
  2. 执行 SetFunctionName (methodDef.[[Closure]], methodDef.[[Key]])。
  3. 返回 ?  DefineMethodProperty (object, methodDef.[[Key]], methodDef.[[Closure]], enumerable)。
MethodDefinition : get ClassElementName ( ) { FunctionBody }
  1. 令 propKey 为 ?  Evaluation ClassElementName 的结果。
  2. 令 env 为 当前执行上下文 的 LexicalEnvironment。
  3. 令 privateEnv 为 当前执行上下文 的 PrivateEnvironment。
  4. 令 sourceText 为 MethodDefinition 匹配的源文本。
  5. 令 formalParameterList 为生产式 FormalParameters : [empty] 的实例。
  6. 令 closure 为 OrdinaryFunctionCreate ( %Function.prototype% , sourceText, formalParameterList, FunctionBody , non-lexical-this, env, privateEnv)。
  7. 执行 MakeMethod (closure, object)。
  8. 执行 SetFunctionName (closure, propKey, "get")。
  9. 如果 propKey 是一个 私有名称 ,则:
    1. 返回 { [[Key]]: propKey, [[Kind]]: accessor, [[Get]]: closure, [[Set]]: undefined } 的 PrivateElement。
  10. 否则:
    1. 令 desc 为 PropertyDescriptor { [[Get]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }。
    2. 执行 ?  DefinePropertyOrThrow (object, propKey, desc)。
    3. 返回 unused。
MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. 令 propKey 为 ?  Evaluation ClassElementName 的结果。
  2. 令 env 为 当前执行上下文 的 LexicalEnvironment。
  3. 令 privateEnv 为 当前执行上下文 的 PrivateEnvironment。
  4. 令 sourceText 为 MethodDefinition 匹配的源文本。
  5. 令 closure 为 OrdinaryFunctionCreate ( %Function.prototype% , sourceText, PropertySetParameterList , FunctionBody , non-lexical-this, env, privateEnv)。
  6. 执行 MakeMethod (closure, object)。
  7. 执行 SetFunctionName (closure, propKey, "set")。
  8. 如果 propKey 是一个 私有名称 ,则:
    1. 返回 { [[Key]]: propKey, [[Kind]]: accessor, [[Get]]: undefined, [[Set]]: closure } 的 PrivateElement。
  9. 否则:
    1. 令 desc 为 PropertyDescriptor { [[Set]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }。
    2. 执行 ?  DefinePropertyOrThrow (object, propKey, desc)。
    3. 返回 unused。
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. 令 propKey 为 ?  Evaluation ClassElementName 的结果。
  2. 令 env 为 当前执行上下文 的 LexicalEnvironment。
  3. 令 privateEnv 为 当前执行上下文 的 PrivateEnvironment。
  4. 令 sourceText 为 GeneratorMethod 匹配的源文本。
  5. 令 closure 为 OrdinaryFunctionCreate ( %GeneratorFunction.prototype% , sourceText, UniqueFormalParameters , GeneratorBody , non-lexical-this, env, privateEnv)。
  6. 执行 MakeMethod (closure, object)。
  7. 执行 SetFunctionName (closure, propKey)。
  8. 令 prototype 为 OrdinaryObjectCreate ( %GeneratorFunction.prototype.prototype% )。
  9. 执行 !  DefinePropertyOrThrow (closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  10. 返回 ?  DefineMethodProperty (object, propKey, closure, enumerable)。
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. 令 propKey 为 ?  Evaluation ClassElementName 的结果。
  2. 令 env 为 当前执行上下文 的 LexicalEnvironment。
  3. 令 privateEnv 为 当前执行上下文 的 PrivateEnvironment。
  4. 令 sourceText 为 AsyncGeneratorMethod 匹配的源文本。
  5. 令 closure 为 OrdinaryFunctionCreate ( %AsyncGeneratorFunction.prototype% , sourceText, UniqueFormalParameters , AsyncGeneratorBody , non-lexical-this, env, privateEnv)。
  6. 执行 MakeMethod (closure, object)。
  7. 执行 SetFunctionName (closure, propKey)。
  8. 令 prototype 为 OrdinaryObjectCreate ( %AsyncGeneratorFunction.prototype.prototype% )。
  9. 执行 !  DefinePropertyOrThrow (closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  10. 返回 ?  DefineMethodProperty (object, propKey, closure, enumerable)。
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. 令 propKey 为 ?  Evaluation ClassElementName 的结果。
  2. 令 env 为 当前执行上下文 的 LexicalEnvironment。
  3. 令 privateEnv 为 当前执行上下文 的 PrivateEnvironment。
  4. 令 sourceText 为 AsyncMethod 匹配的源文本。
  5. 令 closure 为 OrdinaryFunctionCreate ( %AsyncFunction.prototype% , sourceText, UniqueFormalParameters , AsyncFunctionBody , non-lexical-this, env, privateEnv)。
  6. 执行 MakeMethod (closure, object)。
  7. 执行 SetFunctionName (closure, propKey)。
  8. 返回 ?  DefineMethodProperty (object, propKey, closure, enumerable)。

15.5 生成器函数定义

语法

GeneratorDeclaration[Yield, Await, Default] : function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } [+Default] function * ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorExpression : function * BindingIdentifier[+Yield, ~Await]opt ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorMethod[Yield, Await] : * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorBody : FunctionBody[+Yield, ~Await] YieldExpression[In, Await] : yield yield [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await] yield [no LineTerminator here] * AssignmentExpression[?In, +Yield, ?Await] 注意 1

紧接在 yield 之后的语法上下文要求使用 InputElementRegExpOrTemplateTail 词法目标。

注意 2

YieldExpression 不能在生成器函数的 FormalParameters 中使用,因为 FormalParameters 中的任何表达式都在生成器处于可恢复状态之前被评估。

注意 3

与生成器相关的 抽象操作 定义在 27.5.3 中。

15.5.1 静态语义:早期错误

GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody }

15.5.2 运行时语义:EvaluateGeneratorBody

语法导向操作 EvaluateGeneratorBody 接受两个参数:functionObject(一个 ECMAScript 函数对象)和 argumentsList(一个 列表,包含 ECMAScript 语言值), 并返回一个 抛出完成记录 或一个 返回完成记录。 它的定义分为以下几个步骤:

GeneratorBody : FunctionBody
  1. 执行 ? FunctionDeclarationInstantiation(functionObject, argumentsList)。
  2. G 为 ? OrdinaryCreateFromConstructor(functionObject, "%GeneratorFunction.prototype.prototype%",« [[GeneratorState]], [[GeneratorContext]], [[GeneratorBrand]] »)。
  3. G.[[GeneratorBrand]] 设置为 empty
  4. 执行 GeneratorStart(G, FunctionBody)。
  5. 返回 完成记录 { [[Type]]: return, [[Value]]: G, [[Target]]: empty }。

15.5.3 运行时语义:InstantiateGeneratorFunctionObject

语法导向操作 InstantiateGeneratorFunctionObject 接受两个参数:env(一个 环境记录)和 privateEnv(一个 私有环境记录null), 并返回一个 ECMAScript 函数对象。它的定义分为以下几个步骤:

GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody }
  1. nameStringValueBindingIdentifier
  2. sourceText 为与 GeneratorDeclaration 匹配的 GeneratorDeclaration 的源文本。
  3. FOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceTextFormalParametersGeneratorBodynon-lexical-thisenvprivateEnv)。
  4. 执行 SetFunctionName(Fname)。
  5. prototypeOrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
  6. 执行 ! DefinePropertyOrThrow(F"prototype",属性描述符 { [[Value]]: prototype[[Writable]]: true[[Enumerable]]: false[[Configurable]]: false })。
  7. 返回 F
GeneratorDeclaration : function * ( FormalParameters ) { GeneratorBody }
  1. sourceText 为与 GeneratorDeclaration 匹配的 GeneratorDeclaration 的源文本。
  2. FOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceTextFormalParametersGeneratorBodynon-lexical-thisenvprivateEnv)。
  3. 执行 SetFunctionName(F"default")。
  4. prototypeOrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
  5. 执行 ! DefinePropertyOrThrow(F"prototype",属性描述符 { [[Value]]: prototype[[Writable]]: true[[Enumerable]]: false[[Configurable]]: false })。
  6. 返回 F

匿名的 GeneratorDeclaration 只能作为 export default 声明的一部分出现,因此其函数代码始终是 严格模式代码

15.5.4 运行时语义:实例化生成器函数表达式

语法指导操作 实例化生成器函数表达式接收一个可选参数 name(一个 属性键 或一个 私有名称 )并返回一个 ECMAScript 函数对象 。其定义如下:

GeneratorExpression : function * ( FormalParameters ) { GeneratorBody }
  1. 如果 name 不存在,将 name 设为空字符串 ""
  2. env 为当前运行执行上下文的 词法环境
  3. privateEnv 为当前运行执行上下文的 私有环境
  4. sourceText 为与 语法指导操作 GeneratorExpression 匹配的源文本。
  5. closure OrdinaryFunctionCreate ( %GeneratorFunction.prototype% , sourceText, FormalParameters , GeneratorBody , non-lexical-this, env, privateEnv)。
  6. 执行 SetFunctionName (closure, name)。
  7. prototype OrdinaryObjectCreate ( %GeneratorFunction.prototype.prototype% )。
  8. 执行 DefinePropertyOrThrow (closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })。
  9. 返回 closure

15.5.5 运行时语义:求值

GeneratorExpression : function * BindingIdentifier opt ( FormalParameters ) { GeneratorBody }
  1. 返回 InstantiateGeneratorFunctionExpression GeneratorExpression
YieldExpression : yield
  1. 返回 ?  Yield (undefined)。
YieldExpression : yield AssignmentExpression
  1. exprRef 为 ?  Evaluation AssignmentExpression
  2. value 为 ?  GetValue (exprRef)。
  3. 返回 ?  Yield (value)。
YieldExpression : yield * AssignmentExpression
  1. generatorKind GetGeneratorKind ()。
  2. exprRef 为 ?  Evaluation AssignmentExpression
  3. value 为 ?  GetValue (exprRef)。
  4. iteratorRecord 为 ?  GetIterator (value, generatorKind)。
  5. iteratoriteratorRecord.[[Iterator]]
  6. received NormalCompletion (undefined)。
  7. 重复,直到:
    1. 如果 received 正常完成 ,则
      1. innerResult 为 ?  Call (iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « received.[[Value]] »)。
      2. 如果 generatorKindasync,将 innerResult 设为 ?  Await (innerResult)。
      3. 如果 innerResult 不是对象 ,抛出 TypeError 异常。
      4. done 为 ?  IteratorComplete (innerResult)。
      5. 如果 donetrue,则
        1. 返回 ?  IteratorValue (innerResult)。
      6. 如果 generatorKindasync,将 received 设为 Completion (? AsyncGeneratorYield (? IteratorValue (innerResult)))。
      7. 否则,将 received 设为 Completion ( GeneratorYield (innerResult))。
    2. 否则,如果 received throw completion ,则
      1. throw 为 ?  GetMethod (iterator, "throw")。
      2. 如果 throw 不是 undefined,则
        1. innerResult 为 ?  Call (throw, iterator, « received.[[Value]] »)。
        2. 如果 generatorKindasync,将 innerResult 设为 ?  Await (innerResult)。
        3. 注意:内部迭代器的 throw 方法抛出的异常会被传播。throw 方法的正常完成与 next 类似。
        4. 如果 innerResult 不是对象 ,抛出 TypeError 异常。
        5. done 为 ?  IteratorComplete (innerResult)。
        6. 如果 donetrue,则
          1. 返回 ?  IteratorValue (innerResult)。
        7. 如果 generatorKindasync,将 received 设为 Completion ( AsyncGeneratorYield (? IteratorValue (innerResult)))。
        8. 否则,将 received 设为 Completion ( GeneratorYield (innerResult))。
      3. 否则,
        1. 断言 received return completion
        2. return 为 ?  GetMethod (iterator, "return")。
        3. 如果 returnundefined,则
          1. value 设为 received.[[Value]]
          2. 如果 generatorKindasync,则
            1. value 设为 ?  Await (value)。
          3. 返回 Completion Record { [[Type]]: return, [[Value]]: value, [[Target]]: empty  }。
        4. innerReturnResult 为 ?  Call (return, iterator, « received.[[Value]] »)。
        5. 如果 generatorKindasync,将 innerReturnResult 设为 ?  Await (innerReturnResult)。
        6. 如果 innerReturnResult 不是对象 ,抛出 TypeError 异常。
        7. done 为 ?  IteratorComplete (innerReturnResult)。
        8. 如果 donetrue,则
          1. value 设为 ?  IteratorValue (innerReturnResult)。
          2. 返回 Completion Record { [[Type]]: return, [[Value]]: value, [[Target]]: empty  }。
        9. 如果 generatorKindasync,将 received 设为 Completion ( AsyncGeneratorYield (? IteratorValue (innerReturnResult)))。
        10. 否则,将 received 设为 Completion ( GeneratorYield (innerReturnResult))。

15.6 异步生成器函数定义

语法

AsyncGeneratorDeclaration[Yield, Await, Default] : async [no LineTerminator here] function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } [+Default] async [no LineTerminator here] function * ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorExpression : async [no LineTerminator here] function * BindingIdentifier[+Yield, +Await]opt ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorMethod[Yield, Await] : async [no LineTerminator here] * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorBody : FunctionBody[+Yield, +Await] 注意 1

YieldExpression AwaitExpression 不能在异步生成器函数的 FormalParameters 中使用,因为任何属于 FormalParameters 的表达式在生成的 AsyncGenerator 处于可恢复状态之前都会被求值。

注意 2

与 AsyncGenerators 相关的 抽象操作 定义在 27.6.3

15.6.1 静态语义:早期错误

AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifier opt ( FormalParameters ) { AsyncGeneratorBody }

15.6.2 运行时语义:EvaluateAsyncGeneratorBody

语法定向操作 EvaluateAsyncGeneratorBody 接受参数 functionObject(一个 ECMAScript 函数对象 )和 argumentsList(一个 列表 of ECMAScript 语言值 ),并返回一个 throw completion return completion 。它分段定义如下:

AsyncGeneratorBody : FunctionBody
  1. 执行 ?  FunctionDeclarationInstantiation (functionObject, argumentsList)。
  2. generator 为 ?  OrdinaryCreateFromConstructor (functionObject, "%AsyncGeneratorFunction.prototype.prototype%", « [[AsyncGeneratorState]], [[AsyncGeneratorContext]], [[AsyncGeneratorQueue]], [[GeneratorBrand]] »)。
  3. generator.[[GeneratorBrand]] 设为 empty
  4. 执行 AsyncGeneratorStart (generator, FunctionBody )。
  5. 返回 Completion Record { [[Type]]: return, [[Value]]: generator, [[Target]]: empty  }。

15.6.3 运行时语义:InstantiateAsyncGeneratorFunctionObject

语法定向操作 InstantiateAsyncGeneratorFunctionObject 接受参数 env(一个 环境记录 )和 privateEnv(一个 私有环境记录 null),并返回一个 ECMAScript 函数对象 。它分段定义如下:

AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }
  1. name StringValue of BindingIdentifier
  2. sourceText 源文本匹配 AsyncGeneratorDeclaration
  3. F OrdinaryFunctionCreate ( %AsyncGeneratorFunction.prototype% , sourceText, FormalParameters , AsyncGeneratorBody , non-lexical-this, env, privateEnv)。
  4. 执行 SetFunctionName (F, name)。
  5. prototype OrdinaryObjectCreate ( %AsyncGeneratorFunction.prototype.prototype% )。
  6. 执行 !  DefinePropertyOrThrow (F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false  })。
  7. 返回 F
AsyncGeneratorDeclaration : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. sourceText 源文本匹配 AsyncGeneratorDeclaration
  2. F OrdinaryFunctionCreate ( %AsyncGeneratorFunction.prototype% , sourceText, FormalParameters , AsyncGeneratorBody , non-lexical-this, env, privateEnv)。
  3. 执行 SetFunctionName (F, "default")。
  4. prototype OrdinaryObjectCreate ( %AsyncGeneratorFunction.prototype.prototype% )。
  5. 执行 !  DefinePropertyOrThrow (F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false  })。
  6. 返回 F
注意

匿名的 AsyncGeneratorDeclaration 只能作为 export default 声明的一部分出现。

15.6.4 运行时语义:InstantiateAsyncGeneratorFunctionExpression

语法定向操作 InstantiateAsyncGeneratorFunctionExpression 接受可选参数 name(一个 属性键 私有名称 ),并返回一个 ECMAScript 函数对象 。它分段定义如下:

AsyncGeneratorExpression : async function * ( FormalParameters ) { AsyncGeneratorBody }
AsyncGeneratorExpression : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }
注意

AsyncGeneratorExpression 中的 BindingIdentifier 可以在 AsyncGeneratorExpression AsyncGeneratorBody 中被引用,以允许生成器代码递归调用自身。然而,与 AsyncGeneratorDeclaration 不同,在 AsyncGeneratorExpression 中的 BindingIdentifier 不能在外层作用域中被引用,也不会影响包含它的作用域。

15.6.5 运行时语义:评估

AsyncGeneratorExpression : async function * BindingIdentifier opt ( FormalParameters ) { AsyncGeneratorBody }

15.7 类定义

语法

ClassDeclaration[Yield, Await, Default] : class BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await] [+Default] class ClassTail[?Yield, ?Await] ClassExpression[Yield, Await] : class BindingIdentifier[?Yield, ?Await]opt ClassTail[?Yield, ?Await] ClassTail[Yield, Await] : ClassHeritage[?Yield, ?Await]opt { ClassBody[?Yield, ?Await]opt } ClassHeritage[Yield, Await] : extends LeftHandSideExpression[?Yield, ?Await] ClassBody[Yield, Await] : ClassElementList[?Yield, ?Await] ClassElementList[Yield, Await] : ClassElement[?Yield, ?Await] ClassElementList[?Yield, ?Await] ClassElement[?Yield, ?Await] ClassElement[Yield, Await] : MethodDefinition[?Yield, ?Await] static MethodDefinition[?Yield, ?Await] FieldDefinition[?Yield, ?Await] ; static FieldDefinition[?Yield, ?Await] ; ClassStaticBlock ; FieldDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt ClassElementName[Yield, Await] : PropertyName[?Yield, ?Await] PrivateIdentifier ClassStaticBlock : static { ClassStaticBlockBody } ClassStaticBlockBody : ClassStaticBlockStatementList ClassStaticBlockStatementList : StatementList[~Yield, +Await, ~Return]opt 注意

类定义总是 严格模式代码

15.7.1 静态语义:早期错误

ClassTail : ClassHeritage opt { ClassBody } ClassBody : ClassElementList ClassElement : MethodDefinition ClassElement : static MethodDefinition ClassElement : FieldDefinition ; ClassElement : static FieldDefinition ; FieldDefinition : ClassElementName Initializer opt ClassElementName : PrivateIdentifier ClassStaticBlockBody : ClassStaticBlockStatementList

15.7.2 静态语义:ClassElementKind

语法指导操作 ClassElementKind 不接受参数,并返回 constructor-methodnon-constructor-method,或 empty。它在以下各个生成式上分段定义:

ClassElement : MethodDefinition
  1. 如果 PropNameMethodDefinition"constructor",返回 constructor-method
  2. 返回 non-constructor-method
ClassElement : static MethodDefinition FieldDefinition ; static FieldDefinition ;
  1. 返回 non-constructor-method
ClassElement : ClassStaticBlock
  1. 返回 non-constructor-method
ClassElement : ;
  1. 返回 empty

15.7.3 静态语义:ConstructorMethod

语法指导操作 ConstructorMethod 不接受参数,并返回一个 ClassElement 解析节点empty。它在以下各个生成式上分段定义:

ClassElementList : ClassElement
  1. 如果 ClassElementKindClassElementconstructor-method,返回 ClassElement
  2. 返回 empty
ClassElementList : ClassElementList ClassElement
  1. headConstructorMethodClassElementList
  2. 如果 head 不是 empty,返回 head
  3. 如果 ClassElementKindClassElementconstructor-method,返回 ClassElement
  4. 返回 empty
注意

早期错误规则确保只有一个名为 "constructor" 的方法定义,并且它不是 访问器 属性 或生成器定义。

15.7.4 静态语义:IsStatic

语法指导操作 IsStatic 不接受参数,并返回一个布尔值。它在以下各个生成式上分段定义:

ClassElement : MethodDefinition
  1. 返回 false
ClassElement : static MethodDefinition
  1. 返回 true
ClassElement : FieldDefinition ;
  1. 返回 false
ClassElement : static FieldDefinition ;
  1. 返回 true
ClassElement : ClassStaticBlock
  1. 返回 true
ClassElement : ;
  1. 返回 false

15.7.5 静态语义:NonConstructorElements

语法指导操作 NonConstructorElements 不接受参数,并返回一个包含 ClassElement解析节点列表。它在以下各个生成式上分段定义:

ClassElementList : ClassElement
  1. 如果ClassElementKind 属于ClassElement且为non-constructor-method,则
    1. 返回« ClassElement »。
  2. 返回一个新的空列表
ClassElementList : ClassElementList ClassElement
  1. list等于NonConstructorElements 属于ClassElementList
  2. 如果ClassElementKind 属于ClassElement且为non-constructor-method,则
    1. ClassElement追加到list的末尾。
  3. 返回list

15.7.6 静态语义:PrototypePropertyNameList

语法指导操作 PrototypePropertyNameList 不接受参数,并返回一个包含属性键列表。它在以下各个生成式上分段定义:

ClassElementList : ClassElement
  1. propName 等于 PropName 属于 ClassElement
  2. 如果 propNameempty,则返回一个新的空列表
  3. 如果 IsStatic 属于 ClassElementtrue,则返回一个新的空列表
  4. 返回 « propName »。
ClassElementList : ClassElementList ClassElement
  1. list 等于 PrototypePropertyNameList 属于ClassElementList
  2. propName 等于 PropName 属于 ClassElement
  3. 如果 propNameempty,则返回 list
  4. 如果 IsStatic 属于 ClassElementtrue,则返回 list
  5. 返回列表连接 list 和 « propName »。

15.7.7 静态语义:AllPrivateIdentifiersValid

语法指导操作 AllPrivateIdentifiersValid 接受参数 names(一个字符串列表)并返回一个布尔值。

本规范中未列出的每个语法生成式替代项隐含有以下默认的 AllPrivateIdentifiersValid 定义:

  1. 对于此解析节点的每个子节点child,执行以下操作:
    1. 如果 child 是一个非终结符的实例,那么
      1. 如果 AllPrivateIdentifiersValid 属于 child 并带有参数 namesfalse,则返回 false
  2. 返回 true
MemberExpression : MemberExpression . PrivateIdentifier
  1. 如果 names 包含 StringValue 属于 PrivateIdentifier,那么
    1. 返回 AllPrivateIdentifiersValid 属于 MemberExpression 并带有参数 names
  2. 返回 false
CallExpression : CallExpression . PrivateIdentifier
  1. 如果 names 包含 StringValue 属于 PrivateIdentifier,那么
    1. 返回 AllPrivateIdentifiersValid 属于 CallExpression 并带有参数 names
  2. 返回 false
OptionalChain : ?. PrivateIdentifier
  1. 如果 names 包含 StringValue 属于 PrivateIdentifier,返回 true
  2. 返回 false
OptionalChain : OptionalChain . PrivateIdentifier
  1. 如果 names 包含 StringValue 属于 PrivateIdentifier,那么
    1. 返回 AllPrivateIdentifiersValid 属于 OptionalChain 并带有参数 names
  2. 返回 false
ClassBody : ClassElementList
  1. newNames 等于 列表连接 namesPrivateBoundIdentifiers 属于 ClassBody
  2. 返回 AllPrivateIdentifiersValid 属于 ClassElementList 并带有参数 newNames
RelationalExpression : PrivateIdentifier in ShiftExpression
  1. 如果 names 包含 StringValue 属于 PrivateIdentifier,那么
    1. 返回 AllPrivateIdentifiersValid 属于 ShiftExpression 并带有参数 names
  2. 返回 false

15.7.8 静态语义:PrivateBoundIdentifiers

语法指导操作 PrivateBoundIdentifiers 不接受参数并返回一个字符串列表。它通过以下生成式逐步定义:

FieldDefinition : ClassElementName Initializeropt
  1. 返回PrivateBoundIdentifiers 属于 ClassElementName
ClassElementName : PrivateIdentifier
  1. 返回一个列表,其唯一元素是StringValue 属于 PrivateIdentifier
ClassElementName : PropertyName ClassElement : ClassStaticBlock ;
  1. 返回一个新的空列表
ClassElementList : ClassElementList ClassElement
  1. names1PrivateBoundIdentifiers 属于ClassElementList
  2. names2PrivateBoundIdentifiers 属于ClassElement
  3. 返回 names1names2列表连接
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody } GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody } AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. 返回PrivateBoundIdentifiers 属于 ClassElementName

15.7.9 静态语义:ContainsArguments

语法指导操作 ContainsArguments 不接受参数并返回一个布尔值。

本规范中未列出的每个语法生成式替代方案隐式具有以下 ContainsArguments 的默认定义:

  1. 对于此解析节点的每个子节点child,执行以下操作
    1. 如果child是一个非终结符实例,则
      1. 如果ContainsArguments 属于childtrue,则返回true
  2. 返回false
IdentifierReference : Identifier
  1. 如果StringValue 属于 Identifier"arguments",则返回true
  2. 返回false
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }
  1. 返回false
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody } GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody } AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. 返回false
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody } GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody } AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. 返回ContainsArguments 属于ClassElementName

15.7.10 运行时语义: ClassFieldDefinitionEvaluation

ClassFieldDefinitionEvaluation 语法直接操作接收参数 homeObject(一个对象),并返回一个包含 ClassFieldDefinition Record 的正常完成记录或一个 异常完成记录。它根据以下语法规则逐一定义:

FieldDefinition : ClassElementName Initializeropt
  1. name 为 ? Evaluation ClassElementName
  2. 如果 Initializer 存在,那么:
    1. formalParameterListFormalParameters:[empty] 的一个实例。
    2. env运行执行上下文 的词法环境。
    3. privateEnv运行执行上下文 的私有环境。
    4. sourceText 为 Unicode 代码点的空序列。
    5. initializerOrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameterList, Initializer, non-lexical-this, env, privateEnv)。
    6. 执行 MakeMethod(initializer, homeObject)。
    7. 设置 initializer.[[ClassFieldInitializerName]]name
  3. 否则:
    1. initializerempty
  4. 返回 ClassFieldDefinition Record { [[Name]]: name, [[Initializer]]: initializer }。
initializer 创建的函数永远不会直接被 ECMAScript 代码访问。

15.7.11 运行时语义:ClassStaticBlockDefinitionEvaluation

ClassStaticBlockDefinitionEvaluation 语法直接操作接收参数 homeObject(一个对象),并返回一个 ClassStaticBlockDefinition Record。它根据以下语法规则逐一定义:

ClassStaticBlock : static { ClassStaticBlockBody }
  1. lex运行执行上下文 的词法环境。
  2. privateEnv运行执行上下文 的私有环境。
  3. sourceText 为 Unicode 代码点的空序列。
  4. formalParametersFormalParameters:[empty] 的一个实例。
  5. bodyFunctionOrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameters, ClassStaticBlockBody, non-lexical-this, lex, privateEnv)。
  6. 执行 MakeMethod(bodyFunction, homeObject)。
  7. 返回 ClassStaticBlockDefinition Record { [[BodyFunction]]: bodyFunction }。
bodyFunction 创建的函数永远不会直接被 ECMAScript 代码访问。

15.7.12 运行时语义:EvaluateClassStaticBlockBody

EvaluateClassStaticBlockBody 语法直接操作接收参数 functionObject(一个 ECMAScript 函数对象),并返回一个 正常完成记录,包含一个 ECMAScript 语言值,或一个 中断完成。它根据以下语法规则逐一定义:

ClassStaticBlockBody : ClassStaticBlockStatementList
  1. 断言functionObject 是由 ClassStaticBlockDefinitionEvaluation5 步创建的合成函数。
  2. 执行 ! FunctionDeclarationInstantiation(functionObject, « »)。
  3. 返回 ? Evaluation of ClassStaticBlockStatementList

15.7.13 运行时语义:ClassElementEvaluation

语法直接操作 ClassElementEvaluation 接受参数 object(一个对象)并返回一个包含 正常完成 ClassFieldDefinition 记录 ClassStaticBlockDefinition 记录 PrivateElement unused,或返回一个 中止完成 。其分段定义如下生产:

ClassElement : FieldDefinition ; static FieldDefinition ;
  1. 返回 ? ClassFieldDefinitionEvaluation FieldDefinition 参数为 object
ClassElement : MethodDefinition static MethodDefinition
  1. 返回 ? MethodDefinitionEvaluation MethodDefinition 参数为 objectfalse
ClassElement : ClassStaticBlock
  1. 返回 ClassStaticBlockDefinitionEvaluation ClassStaticBlock 参数为 object
ClassElement : ;
  1. 返回 unused

15.7.14 运行时语义:ClassDefinitionEvaluation

语法直接操作 ClassDefinitionEvaluation 接受参数 classBinding(字符串或undefined)和 className 属性键 私有名称 ),并返回一个包含 正常完成 函数对象 中止完成

注意

为了方便规范,私有方法和访问器与私有字段一起包含在类实例的 [[PrivateElements]] 插槽中。然而,任何给定对象都具有某个类定义的所有或无任何私有方法和访问器。此功能的设计使得实现可以选择使用不需要单独跟踪每个方法或访问器的策略来实现私有方法和访问器。

例如,实现可以直接将实例私有方法与相应的 私有名称 相关联,并跟踪每个对象,哪些类 构造函数 已经使用该对象作为它们的 this 值运行。然后在对象上查找实例私有方法的过程是检查定义该方法的类 构造函数 是否已用于初始化该对象,然后返回与 私有名称 相关的方法。

这与私有字段不同:因为字段初始化程序在类实例化期间可能会抛出异常,个别对象可能具有给定类的某些私有字段的子集,因此一般需要单独跟踪私有字段。

其分段定义如下生产:

ClassTail : ClassHeritage opt { ClassBody opt }
  1. env 运行执行上下文 的 LexicalEnvironment。
  2. classEnv NewDeclarativeEnvironment (env)。
  3. 如果 classBinding 不是 undefined,则
    1. 执行 ! classEnv.CreateImmutableBinding(classBinding, true)。
  4. outerPrivateEnvironment 运行执行上下文 的 PrivateEnvironment。
  5. classPrivateEnvironment NewPrivateEnvironment (outerPrivateEnvironment)。
  6. 如果 ClassBody 存在,则
    1. 对于 PrivateBoundIdentifiers 的每个字符串 dn,都
      1. 如果 classPrivateEnvironment.[[Names]] 包含一个 私有名称 pn,且 pn.[[Description]]dn,则
        1. 断言 :这仅对 getter/setter 对可能。
      2. 否则,
        1. name 为新的 私有名称 ,其 [[Description]]dn
        2. name 添加到 classPrivateEnvironment.[[Names]]
  7. 如果 ClassHeritage 不存在,则
    1. protoParent %Object.prototype%
    2. constructorParent %Function.prototype%
  8. 否则,
    1. 运行执行上下文 的 LexicalEnvironment 设置为 classEnv
    2. 注意:在评估 ClassHeritage 时, 运行执行上下文 的 PrivateEnvironment 是 outerPrivateEnvironment
    3. superclassRef Completion ( Evaluation ClassHeritage )。
    4. 运行执行上下文 的 LexicalEnvironment 设置为 env
    5. superclass 为 ?  GetValue (? superclassRef)。
    6. 如果 superclassnull,则
      1. protoParentnull
      2. constructorParent %Function.prototype%
    7. 否则如果 IsConstructor (superclass) 是 false,则
      1. 抛出一个 TypeError 异常。
    8. 否则,
      1. protoParent 为 ?  Get (superclass, "prototype")。
      2. 如果 protoParent 不是一个对象 protoParent 不是 null,则抛出一个 TypeError 异常。
      3. constructorParentsuperclass
  9. proto OrdinaryObjectCreate (protoParent)。
  10. 如果 ClassBody 不存在,令 constructorempty
  11. 否则,令 constructor ConstructorMethod ClassBody
  12. 运行执行上下文 的 LexicalEnvironment 设置为 classEnv
  13. 运行执行上下文 的 PrivateEnvironment 设置为 classPrivateEnvironment
  14. 如果 constructorempty,则
    1. defaultConstructor 为一个新的 抽象闭包 ,它没有参数且不捕获任何内容,当被调用时执行以下步骤:
      1. args 为传递给此函数的由 [[Call]][[Construct]] 传递的参数列表。
      2. 如果 NewTarget 是 undefined,则抛出一个 TypeError 异常。
      3. F 活动函数对象
      4. 如果 F.[[ConstructorKind]]derived,则
        1. 注意:此分支的行为类似于 constructor(...args) { super(...args); }。最显著的区别在于,虽然前述的 ECMAScript 源代码 可观察到调用 %Array.prototype% 上的 @@iterator 方法,但此函数不会。
        2. func 为 ! F.[[GetPrototypeOf]]()。
        3. 如果 IsConstructor (func) 是 false,则抛出一个 TypeError 异常。
        4. result 为 ?  Construct (func, args, NewTarget)。
      5. 否则,
        1. 注意:此分支的行为类似于 constructor() {}
        2. result 为 ?  OrdinaryCreateFromConstructor (NewTarget, "%Object.prototype%")。
      6. 执行 ?  InitializeInstanceElements (result, F)。
      7. 返回 result
    2. F CreateBuiltinFunction (defaultConstructor, 0, className, « [[ConstructorKind]], [[SourceText]] », 当前 Realm 记录 , constructorParent)。
  15. 否则,
    1. constructorInfo 为 !  DefineMethod (constructor,带参数 protoconstructorParent)。
    2. FconstructorInfo.[[Closure]]
    3. 执行 MakeClassConstructor (F)。
    4. 执行 SetFunctionName (F, className)。
  16. 执行 MakeConstructor (F, false, proto)。
  17. 如果 ClassHeritage 存在,设置 F.[[ConstructorKind]]derived
  18. 执行 !  DefineMethodProperty (proto, "constructor", F, false)。
  19. 如果 ClassBody 不存在,令 elements 为一个新的空的 列表
  20. 否则,令 elements NonConstructorElements ClassBody
  21. instancePrivateMethods 为一个新的空的 列表
  22. staticPrivateMethods 为一个新的空的 列表
  23. instanceFields 为一个新的空的 列表
  24. staticElements 为一个新的空的 列表
  25. 对于 elements 的每个 ClassElement e,执行
    1. 如果 IsStatic efalse,则
      1. element Completion ( ClassElementEvaluation e 带参数 proto)。
    2. 否则,
      1. element Completion ( ClassElementEvaluation e 带参数 F)。
    3. 如果 element 是一个 中止完成 ,则
      1. 运行执行上下文 的 LexicalEnvironment 设置为 env
      2. 运行执行上下文 的 PrivateEnvironment 设置为 outerPrivateEnvironment
      3. 返回 ? element
    4. 设置 element 为 ! element
    5. 如果 element 是一个 PrivateElement ,则
      1. 断言 element.[[Kind]] 不是 methodaccessor
      2. 如果 IsStatic efalse,令 containerinstancePrivateMethods
      3. 否则,令 containerstaticPrivateMethods
      4. 如果 container 包含一个 PrivateElement pe,且 pe.[[Key]]element.[[Key]],则
        1. 断言 element.[[Kind]]pe.[[Kind]] 均为 accessor
        2. 如果 element.[[Get]]undefined,则
          1. combined PrivateElement { [[Key]]: element.[[Key]], [[Kind]]: accessor, [[Get]]: pe.[[Get]], [[Set]]: element.[[Set]] }。
        3. 否则,
          1. combined PrivateElement { [[Key]]: element.[[Key]], [[Kind]]: accessor, [[Get]]: element.[[Get]], [[Set]]: pe.[[Set]] }。
        4. combined 替换 container 中的 pe
      5. 否则,
        1. element 添加到 container
    6. 否则如果 element 是一个 ClassFieldDefinition 记录 ,则
      1. 如果 IsStatic efalse,将 element 添加到 instanceFields
      2. 否则,将 element 添加到 staticElements
    7. 否则如果 element 是一个 ClassStaticBlockDefinition 记录 ,则
      1. element 添加到 staticElements
  26. 运行执行上下文 的 LexicalEnvironment 设置为 env
  27. 如果 classBinding 不是 undefined,则
    1. 执行 ! classEnv.InitializeBinding(classBinding, F)。
  28. 设置 F.[[PrivateMethods]]instancePrivateMethods
  29. 设置 F.[[Fields]]instanceFields
  30. 对于 staticPrivateMethods 的每个 PrivateElement method,执行
    1. 执行 !  PrivateMethodOrAccessorAdd (F, method)。
  31. 对于 staticElements 的每个 elementRecord,执行
    1. 如果 elementRecord 是一个 ClassFieldDefinition 记录 ,则
      1. result Completion ( DefineField (F, elementRecord))。
    2. 否则,
      1. 断言 elementRecord 是一个 ClassStaticBlockDefinition 记录
      2. result Completion ( Call (elementRecord.[[BodyFunction]], F))。
    3. 如果 result 是一个 中止完成 ,则
      1. 运行执行上下文 的 PrivateEnvironment 设置为 outerPrivateEnvironment
      2. 返回 ? result
  32. 运行执行上下文 的 PrivateEnvironment 设置为 outerPrivateEnvironment
  33. 返回 F

15.7.15 Runtime语义: BindingClassDeclarationEvaluation

语法指向操作 BindingClassDeclarationEvaluation 不接受参数,并返回 包含 函数对象 的正常完成或 突然完成 。它分块定义如下:

ClassDeclaration : class BindingIdentifier ClassTail
  1. className StringValue of BindingIdentifier
  2. value 为 ?  ClassDefinitionEvaluation of ClassTail with arguments classNameclassName
  3. value.[[SourceText]] 设置为 ClassDeclaration 匹配的源代码文本。
  4. env 运行执行上下文 的词法环境。
  5. 执行 ?  InitializeBoundName (className, value, env)。
  6. 返回 value
ClassDeclaration : class ClassTail
  1. value 为 ?  ClassDefinitionEvaluation of ClassTail with arguments undefined"default"
  2. value.[[SourceText]] 设置为 ClassDeclaration 匹配的源代码文本。
  3. 返回 value
注意

ClassDeclaration : class ClassTail 仅在作为 ExportDeclaration 的一部分时出现,并且其绑定的建立在该生成的评估操作中处理。详见 16.2.3.7

15.7.16 Runtime语义: Evaluation

ClassDeclaration : class BindingIdentifier ClassTail
  1. 执行 ?  BindingClassDeclarationEvaluation of this ClassDeclaration
  2. 返回 empty
注意

ClassDeclaration : class ClassTail 仅在作为 ExportDeclaration 的一部分时出现,并且从不直接求值。

ClassExpression : class ClassTail
  1. value 为 ?  ClassDefinitionEvaluation of ClassTail with arguments undefined""
  2. value.[[SourceText]] 设置为 ClassExpression 匹配的源代码文本。
  3. 返回 value
ClassExpression : class BindingIdentifier ClassTail
  1. className StringValue of BindingIdentifier
  2. value 为 ?  ClassDefinitionEvaluation of ClassTail with arguments classNameclassName
  3. value.[[SourceText]] 设置为 ClassExpression 匹配的源代码文本。
  4. 返回 value
ClassElementName : PrivateIdentifier
  1. privateIdentifier StringValue of PrivateIdentifier
  2. privateEnvRec running execution context 的 PrivateEnvironment。
  3. namesprivateEnvRec.[[Names]]
  4. 断言 : names 中正好有一个元素是 Private Name ,其 [[Description]]privateIdentifier
  5. privateName Private Name 中的 names,其 [[Description]]privateIdentifier
  6. 返回 privateName
ClassStaticBlockStatementList : [empty]
  1. 返回 undefined

15.8 异步函数定义

语法

AsyncFunctionDeclaration [Yield, Await, Default] : async [no LineTerminator here] function BindingIdentifier [?Yield, ?Await] ( FormalParameters [~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [no LineTerminator here] function ( FormalParameters [~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [no LineTerminator here] function BindingIdentifier [~Yield, +Await] opt ( FormalParameters [~Yield, +Await] ) { AsyncFunctionBody } AsyncMethod [Yield, Await] : async [no LineTerminator here] ClassElementName [?Yield, ?Await] ( UniqueFormalParameters [~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionBody : FunctionBody [~Yield, +Await] AwaitExpression [Yield] : await UnaryExpression [?Yield, +Await] 注释 1

[Await] 参数存在时,await 作为 关键字 解析为 AwaitExpression [Await] 参数在以下上下文的顶层存在,尽管根据非终结符的不同,参数可能在某些上下文中不存在,例如 FunctionBody

脚本 是语法 目标符号 时,当 [Await] 参数不存在时,await 可以作为标识符解析。这包括以下上下文:

注释 2

不同于 YieldExpression ,省略 AwaitExpression 的操作数是语法错误。必须等待某物。

15.8.1 静态语义:早期错误

AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifier opt ( FormalParameters ) { AsyncFunctionBody }

15.8.2 运行时语义:实例化异步函数对象

语法定向操作 InstantiateAsyncFunctionObject 接受参数 env 环境记录 )和 privateEnv PrivateEnvironment 记录 null),并返回 ECMAScript 函数对象 。它按以下生成式逐步定义:

AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }
  1. name StringValue BindingIdentifier
  2. sourceText 源文本匹配 AsyncFunctionDeclaration
  3. F OrdinaryFunctionCreate ( %AsyncFunction.prototype% , sourceText, FormalParameters , AsyncFunctionBody , non-lexical-this, env, privateEnv)。
  4. 执行 SetFunctionName (F, name)。
  5. 返回 F
AsyncFunctionDeclaration : async function ( FormalParameters ) { AsyncFunctionBody }
  1. sourceText 源文本匹配 AsyncFunctionDeclaration
  2. F OrdinaryFunctionCreate ( %AsyncFunction.prototype% , sourceText, FormalParameters , AsyncFunctionBody , non-lexical-this, env, privateEnv)。
  3. 执行 SetFunctionName (F, "default")。
  4. 返回 F

15.8.3 运行时语义:实例化异步函数表达式

语法定向操作 InstantiateAsyncFunctionExpression 接受可选参数 name 属性键 私有名称 ),并返回 ECMAScript 函数对象 。它按以下生成式逐步定义:

AsyncFunctionExpression : async function ( FormalParameters ) { AsyncFunctionBody }
  1. 如果 name 不存在,则将 name 设置为 ""
  2. env 当前执行上下文 的 LexicalEnvironment。
  3. privateEnv 当前执行上下文 的 PrivateEnvironment。
  4. sourceText 源文本匹配 AsyncFunctionExpression
  5. closure OrdinaryFunctionCreate ( %AsyncFunction.prototype% , sourceText, FormalParameters , AsyncFunctionBody , non-lexical-this, env, privateEnv)。
  6. 执行 SetFunctionName (closure, name)。
  7. 返回 closure
AsyncFunctionExpression : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }
  1. 断言 name 不存在。
  2. name 设置为 StringValue BindingIdentifier
  3. outerEnv 当前执行上下文 的 LexicalEnvironment。
  4. funcEnv NewDeclarativeEnvironment (outerEnv)。
  5. 执行 ! funcEnv.CreateImmutableBinding(name, false)。
  6. privateEnv 当前执行上下文 的 PrivateEnvironment。
  7. sourceText 源文本匹配 AsyncFunctionExpression
  8. closure OrdinaryFunctionCreate ( %AsyncFunction.prototype% , sourceText, FormalParameters , AsyncFunctionBody , non-lexical-this, funcEnv, privateEnv)。
  9. 执行 SetFunctionName (closure, name)。
  10. 执行 ! funcEnv.InitializeBinding(name, closure)。
  11. 返回 closure
注释

BindingIdentifier 可以从 AsyncFunctionExpression 内部引用,允许函数递归调用自身。然而,与 FunctionDeclaration 不同, BindingIdentifier AsyncFunctionExpression 中不能从并且不影响 AsyncFunctionExpression 的包围范围引用。

15.8.4 运行时语义:评估异步函数体

语法定向操作 EvaluateAsyncFunctionBody 接受参数 functionObject(ECMAScript 函数对象 )和 argumentsList 列表 ECMAScript 语言值 ),并返回 返回完成 。它按以下生成式逐步定义:

AsyncFunctionBody : FunctionBody
  1. promiseCapability 为 ! NewPromiseCapability ( %Promise% )。
  2. declResult Completion ( FunctionDeclarationInstantiation (functionObject, argumentsList))。
  3. 如果 declResult 突然完成 ,则
    1. 执行 ! Call (promiseCapability.[[Reject]], undefined, «declResult.[[Value]]»)。
  4. 否则,
    1. 执行 AsyncFunctionStart (promiseCapability, FunctionBody )。
  5. 返回 完成记录 { [[Type]]: return, [[Value]]: promiseCapability.[[Promise]], [[Target]]: empty }。

15.8.5 运行时语义:评估

AsyncFunctionExpression : async function BindingIdentifier opt ( FormalParameters ) { AsyncFunctionBody }
  1. 返回 InstantiateAsyncFunctionExpression AsyncFunctionExpression
AwaitExpression : await UnaryExpression
  1. exprRef 为 ? Evaluation UnaryExpression
  2. value 为 ? GetValue (exprRef)。
  3. 返回 ? Await (value)。

15.9 Async Arrow Function 定义

语法

AsyncArrowFunction [In, Yield, Await] : async [no LineTerminator here] AsyncArrowBindingIdentifier [?Yield] [no LineTerminator here] => AsyncConciseBody [?In] CoverCallExpressionAndAsyncArrowHead [?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody [?In] AsyncConciseBody [In] : [lookahead ≠ {] ExpressionBody [?In, +Await] { AsyncFunctionBody } AsyncArrowBindingIdentifier [Yield] : BindingIdentifier [?Yield, +Await] CoverCallExpressionAndAsyncArrowHead [Yield, Await] : MemberExpression [?Yield, ?Await] Arguments [?Yield, ?Await]

补充语法

当处理以下生成式的一个实例时
AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
CoverCallExpressionAndAsyncArrowHead 的解释使用以下语法进行细化:

AsyncArrowHead : async [no LineTerminator here] ArrowFormalParameters [~Yield, +Await]

15.9.1 静态语义:早期错误

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody

15.9.2 静态语义:AsyncConciseBodyContainsUseStrict

语法导向操作 AsyncConciseBodyContainsUseStrict 不接受任何参数,并返回一个布尔值。它在以下生成式上逐步定义:

AsyncConciseBody : ExpressionBody
  1. 返回 false
AsyncConciseBody : { AsyncFunctionBody }
  1. 返回 FunctionBodyContainsUseStrict AsyncFunctionBody

15.9.3 运行时语义:EvaluateAsyncConciseBody

语法导向操作 EvaluateAsyncConciseBody 接受参数 functionObject(一个 ECMAScript 函数对象 )和 argumentsList(一个 列表 ECMAScript 语言值 ),并返回一个 返回完成记录 。它在以下生成式上逐步定义:

AsyncConciseBody : ExpressionBody
  1. promiseCapability 为 !  NewPromiseCapability ( %Promise% )。
  2. declResult Completion ( FunctionDeclarationInstantiation (functionObject, argumentsList))。
  3. 如果 declResult 是一个 突然完成 ,则
    1. 执行 !  Call (promiseCapability.[[Reject]]undefined,« declResult.[[Value]] »)。
  4. 否则,
    1. 执行 AsyncFunctionStart (promiseCapability ExpressionBody )。
  5. 返回 完成记录 { [[Type]]: return[[Value]]: promiseCapability.[[Promise]][[Target]]: empty }。

15.9.4 运行时语义:InstantiateAsyncArrowFunctionExpression

语法导向操作 InstantiateAsyncArrowFunctionExpression 接受可选参数 name(一个 属性键 私有名称 ),并返回一个 ECMAScript 函数对象 。它在以下生成式上逐步定义:

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody
  1. 如果 name 不存在,将 name 设置为 ""
  2. env 运行执行上下文 的 LexicalEnvironment。
  3. privateEnv 运行执行上下文 的 PrivateEnvironment。
  4. sourceText 匹配的源文本 AsyncArrowFunction
  5. parameters AsyncArrowBindingIdentifier
  6. closure OrdinaryFunctionCreate ( %AsyncFunction.prototype% , sourceText, parameters, AsyncConciseBody , lexical-this, env, privateEnv)。
  7. 执行 SetFunctionName (closure, name)。
  8. 返回 closure
AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. 如果 name 不存在,将 name 设置为 ""
  2. env 运行执行上下文 的 LexicalEnvironment。
  3. privateEnv 运行执行上下文 的 PrivateEnvironment。
  4. sourceText 匹配的源文本 AsyncArrowFunction
  5. head AsyncArrowHead 覆盖的 CoverCallExpressionAndAsyncArrowHead
  6. parameters ArrowFormalParameters head
  7. closure OrdinaryFunctionCreate ( %AsyncFunction.prototype% , sourceText, parameters, AsyncConciseBody , lexical-this, env, privateEnv)。
  8. 执行 SetFunctionName (closure, name)。
  9. 返回 closure

15.9.5 运行时语义:评估

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. 返回 InstantiateAsyncArrowFunctionExpression AsyncArrowFunction

15.10 尾调用

15.10.1 静态语义:IsInTailPosition ( call )

抽象操作 IsInTailPosition 接受参数 call(一个 CallExpression 解析节点,一个 MemberExpression 解析节点,或者一个 OptionalChain 解析节点),并返回一个布尔值。它在调用时执行以下步骤:

  1. 如果 源文本匹配 call非严格模式代码,返回 false
  2. 如果 call 不包含在 FunctionBodyConciseBodyAsyncConciseBody 中,返回 false
  3. body 为最紧密包含 callFunctionBodyConciseBodyAsyncConciseBody
  4. 如果 bodyFunctionBodyGeneratorBody,返回 false
  5. 如果 bodyFunctionBodyAsyncFunctionBody,返回 false
  6. 如果 bodyFunctionBodyAsyncGeneratorBody,返回 false
  7. 如果 bodyAsyncConciseBody,返回 false
  8. 返回 HasCallInTailPositionbody 上的结果,参数为 call
注意

尾调用仅在 严格模式代码 中定义,因为有一个常见的非标准语言扩展(见 10.2.4)使得可以观察到调用链上下文。

15.10.2 静态语义:HasCallInTailPosition

语法导向操作 HasCallInTailPosition 接受参数 call(一个 CallExpression 解析节点,一个 MemberExpression 解析节点,或者一个 OptionalChain 解析节点),并返回一个布尔值。

注意 1

call 是一个 解析节点,表示源文本的特定范围。当以下算法将 call 与另一个 解析节点 进行比较时,实际上是在测试它们是否表示相同的源文本。

注意 2

紧接在 GetValue 操作的潜在尾调用也是可能的尾调用。函数调用不能返回 引用记录,因此这样的 GetValue 操作将始终返回与实际函数调用结果相同的值。

它的定义依赖于以下几种产生式:

StatementList : StatementList StatementListItem
  1. hasHasCallInTailPosition 对于 StatementList 的结果,参数为 call
  2. 如果 hastrue,则返回 true
  3. 返回 HasCallInTailPosition 对于 StatementListItem 的结果,参数为 call
FunctionStatementList : [empty] StatementListItem : Declaration Statement : VariableStatement EmptyStatement ExpressionStatement ContinueStatement BreakStatement ThrowStatement DebuggerStatement Block : { } ReturnStatement : return ; LabelledItem : FunctionDeclaration ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement CaseBlock : { }
  1. 返回 false
IfStatement : if ( Expression ) Statement else Statement
  1. has 为第一个 StatementHasCallInTailPosition 的结果,参数为 call
  2. 如果 hastrue,返回 true
  3. 返回第二个 StatementHasCallInTailPosition 的结果,参数为 call
IfStatement : if ( Expression ) Statement DoWhileStatement : do Statement while ( Expression ) ; WhileStatement : while ( Expression ) Statement ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement WithStatement : with ( Expression ) Statement
  1. 返回第一个 StatementHasCallInTailPosition 的结果,参数为 call
LabelledStatement : LabelIdentifier : LabelledItem
  1. 返回第一个 LabelledItemHasCallInTailPosition 的结果,参数为 call
ReturnStatement : return Expression ;
  1. 返回第一个 ExpressionHasCallInTailPosition 的结果,参数为 call
SwitchStatement : switch ( Expression ) CaseBlock
  1. 返回 HasCallInTailPositionCaseBlock 的结果,参数为 call
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. hasfalse
  2. 如果存在第一个 CaseClauses,则将 has 设为 HasCallInTailPosition 对第一个 CaseClauses 的结果,参数为 call
  3. 如果 hastrue,则返回 true
  4. has 设为 HasCallInTailPositionDefaultClause 的结果,参数为 call
  5. 如果 hastrue,则返回 true
  6. 如果存在第二个 CaseClauses,则将 has 设为 HasCallInTailPosition 对第二个 CaseClauses 的结果,参数为 call
  7. 返回 has
CaseClauses : CaseClauses CaseClause
  1. hasHasCallInTailPositionCaseClauses 的结果,参数为 call
  2. 如果 hastrue,则返回 true
  3. 返回 HasCallInTailPositionCaseClause 的结果,参数为 call
CaseClause : case Expression : StatementListopt DefaultClause : default : StatementListopt
  1. 如果存在 StatementList,则返回 HasCallInTailPositionStatementList 的结果,参数为 call
  2. 返回 false
TryStatement : try Block Catch
  1. 返回 HasCallInTailPositionCatch 的结果,参数为 call
TryStatement : try Block Finally try Block Catch Finally
  1. 返回 HasCallInTailPositionFinally 的结果,参数为 call
Catch : catch ( CatchParameter ) Block
  1. 返回 HasCallInTailPositionBlock 的结果,参数为 call
AssignmentExpression : YieldExpression ArrowFunction AsyncArrowFunction LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression CallExpression : SuperCall ImportCall CallExpression [ Expression ] CallExpression . IdentifierName CallExpression . PrivateIdentifier NewExpression : new NewExpression MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier PrimaryExpression : this IdentifierReference Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral
  1. 返回 false
Expression : AssignmentExpression Expression , AssignmentExpression
  1. 返回 HasCallInTailPositionAssignmentExpression 的调用,参数为 call
ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
  1. has 为第一个 AssignmentExpressionHasCallInTailPosition 调用,参数为 call
  2. 如果 hastrue,返回 true
  3. 返回第二个 AssignmentExpressionHasCallInTailPosition 调用,参数为 call
LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
  1. 返回 HasCallInTailPositionBitwiseORExpression 的 调用,参数为 call
LogicalORExpression : LogicalORExpression || LogicalANDExpression
  1. 返回 HasCallInTailPositionLogicalANDExpression 的 调用,参数为 call
CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
  1. 返回 HasCallInTailPositionBitwiseORExpression 的 调用,参数为 call
CallExpression : CoverCallExpressionAndAsyncArrowHead CallExpression Arguments CallExpression TemplateLiteral
  1. 如果此 CallExpressioncall,则返回 true
  2. 返回 false
OptionalExpression : MemberExpression OptionalChain CallExpression OptionalChain OptionalExpression OptionalChain
  1. 返回 HasCallInTailPositionOptionalChain 的结果,参数为 call
OptionalChain : ?. [ Expression ] ?. IdentifierName ?. PrivateIdentifier OptionalChain [ Expression ] OptionalChain . IdentifierName OptionalChain . PrivateIdentifier
  1. 返回 false
OptionalChain : ?. Arguments OptionalChain Arguments
  1. 如果这个 OptionalChaincall,则返回 true
  2. 返回 false
MemberExpression : MemberExpression TemplateLiteral
  1. 如果这个 MemberExpressioncall,则返回 true
  2. 返回 false
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. expr 为由 ParenthesizedExpression 表示的表达式,该表达式由 覆盖,由 CoverParenthesizedExpressionAndArrowParameterList 包含。
  2. 返回 HasCallInTailPositionexpr 和参数 call 的结果。
ParenthesizedExpression : ( Expression )
  1. 返回 HasCallInTailPositionExpression 和参数 call 的结果。

15.10.3 PrepareForTailCall ( )

抽象操作 PrepareForTailCall 不接受任何参数,并返回 unused。调用时执行以下步骤:

  1. 断言:当前的 执行上下文 不会随后用于任何 ECMAScript 代码或内置函数的评估。在调用此抽象操作之后,调用 Call 将创建并推送一个新的 执行上下文,然后再执行任何这样的评估。
  2. 丢弃与当前的 执行上下文 相关的所有资源。
  3. 返回 unused

尾位置调用必须在调用目标函数之前释放当前执行函数的任何瞬态内部资源 执行上下文,或者重新利用这些资源来支持目标函数。

例如,尾位置调用应该仅在目标函数的激活记录的大小超出调用函数的激活记录大小时,才增加实现的激活记录栈的大小。如果目标函数的激活记录更小,则栈的总大小应减少。

16 ECMAScript 语言:脚本和模块

16.1 脚本

语法

Script : ScriptBodyopt ScriptBody : StatementList[~Yield, ~Await, ~Return]

16.1.1 静态语义:早期错误

Script : ScriptBody ScriptBody : StatementList

16.1.2 静态语义:IsStrict

语法导向操作 syntax-directed operation IsStrict 不接受任何参数,并返回一个布尔值。它在以下产生式上逐步定义:

Script : ScriptBodyopt
  1. 如果 ScriptBody 存在且 Directive Prologue 中包含 Use Strict Directive,则返回 true;否则,返回 false

16.1.3 运行时语义:评估

Script : [空]
  1. 返回 undefined

16.1.4 脚本记录

脚本记录 封装了有关正在评估的脚本的信息。每个脚本记录包含了 表 40 中列出的字段。

表 40: 脚本记录 字段
字段名称 值类型 含义
[[Realm]] 一个 Realm 记录undefined 此脚本创建时所在的 realm。如果尚未分配,则为 undefined
[[ECMAScriptCode]] 一个 脚本 解析节点 解析此脚本的源文本后的结果。
[[LoadedModules]] 一个 列表,其中包含 记录,字段包括 [[Specifier]](字符串)和 [[Module]]模块记录 从此脚本导入的规范符字符串到解析的 模块记录 的映射。列表中不会包含两个具有相同 [[Specifier]] 的不同 记录
[[HostDefined]] 任何东西(默认值为 empty 宿主环境 使用的字段,用于与脚本关联附加信息。

16.1.5 解析脚本 ( sourceText, realm, hostDefined )

抽象操作 ParseScript 接受以下参数:sourceTextECMAScript 源文本)、realm(一个 Realm 记录undefined)、以及 hostDefined(任何值),并返回一个 脚本记录 或一个非空的 列表SyntaxError 对象。它基于将 sourceText 解析为 脚本 的结果创建一个 脚本记录。调用时,它执行以下步骤:

  1. script 设为 ParseText(sourceText, 脚本)。
  2. 如果 script 是一个错误的 列表,则返回 script
  3. 返回 脚本记录 { [[Realm]]: realm, [[ECMAScriptCode]]: script, [[LoadedModules]]: « », [[HostDefined]]: hostDefined }。
注意

实现可以在对脚本源文本进行 ParseScript 之前解析脚本源文本并分析其早期错误条件。然而,任何错误的报告必须推迟到本规范实际对该源文本执行 ParseScript 的时候。

16.1.6 脚本评估 ( scriptRecord )

抽象操作 ScriptEvaluation 接受一个参数 scriptRecord(一个 脚本记录),并返回一个 正常完成,其中包含一个 ECMAScript 语言值,或者一个 突然完成。调用时,它执行以下步骤:

  1. globalEnv 设为 scriptRecord.[[Realm]].[[GlobalEnv]]
  2. scriptContext 设为一个新的 ECMAScript 代码执行上下文
  3. scriptContext 的 Function 设为 null
  4. Realm 设为 scriptContext[[Realm]]
  5. scriptContext 的 ScriptOrModule 设为 scriptRecord
  6. scriptContext 的 VariableEnvironment 设为 globalEnv
  7. scriptContext 的 LexicalEnvironment 设为 globalEnv
  8. scriptContext 的 PrivateEnvironment 设为 null
  9. 挂起 运行中的执行上下文
  10. scriptContext 推送到 执行上下文栈;此时 scriptContext运行中的执行上下文
  11. script 设为 scriptRecord.[[ECMAScriptCode]]
  12. result 设为 Completion(GlobalDeclarationInstantiation(script, globalEnv))。
  13. 如果 result 是一个 正常完成,则
    1. result 设为 Completion(Evaluation of script)。
    2. 如果 result 是一个 正常完成result.[[Value]]empty,则
      1. result 设为 NormalCompletion(undefined)。
  14. 挂起 scriptContext 并将其从 执行上下文栈 中移除。
  15. Assert: 执行上下文栈 不能为空。
  16. 恢复当前在 执行上下文栈 顶部的上下文作为 运行中的执行上下文
  17. 返回 ? result

16.1.7 GlobalDeclarationInstantiation ( script, env )

抽象操作 GlobalDeclarationInstantiation 接受两个参数:script(一个 Script,即脚本)和 env(一个 Global Environment Record,即全局环境记录),并返回一个正常完成记录或一个抛出完成记录。script 是正在建立执行上下文的脚本,env 是要创建绑定的全局环境。

注 1

在为脚本评估建立执行上下文时,声明会在当前全局环境中被实例化。代码中声明的每个全局绑定都会被实例化。

调用时执行以下步骤:

  1. lexNamesLexicallyDeclaredNamesscript
  2. varNamesVarDeclaredNamesscript
  3. lexNames 的每个元素 name 执行
    1. 如果 env.HasVarDeclaration(name) 为 true,抛出 SyntaxError 异常。
    2. 如果 env.HasLexicalDeclaration(name) 为 true,抛出 SyntaxError 异常。
    3. hasRestrictedGlobal 为 ? env.HasRestrictedGlobalProperty(name)。
    4. 如果 hasRestrictedGlobaltrue,抛出 SyntaxError 异常。
  4. varNames 的每个元素 name 执行
    1. 如果 env.HasLexicalDeclaration(name) 为 true,抛出 SyntaxError 异常。
  5. varDeclarationsVarScopedDeclarationsscript
  6. functionsToInitialize 为一个新的空的 List
  7. declaredFunctionNames 为一个新的空的 List
  8. varDeclarations 的每个元素 d(按逆序 List 顺序)执行
    1. 如果 d 既不是 VariableDeclaration,也不是 ForBinding,或 BindingIdentifier,则
      1. Assertd 是一个 FunctionDeclarationGeneratorDeclarationAsyncFunctionDeclaration,或 AsyncGeneratorDeclaration
      2. 注意:如果有多个相同名称的函数声明,则使用最后一个声明。
      3. fnd 的唯一元素的 BoundNames
      4. 如果 declaredFunctionNames 中不包含 fn,则
        1. fnDefinable 为 ? env.CanDeclareGlobalFunction(fn)。
        2. 如果 fnDefinablefalse,抛出 TypeError 异常。
        3. fn 添加到 declaredFunctionNames 中。
        4. d 作为第一个元素插入到 functionsToInitialize 中。
  9. declaredVarNames 为一个新的空的 List
  10. varDeclarations 的每个元素 d 执行
    1. 如果 dVariableDeclarationForBinding,或 BindingIdentifier,则
      1. dBoundNames 的每个字符串 vn 执行
        1. 如果 declaredFunctionNames 中不包含 vn,则
          1. vnDefinable 为 ? env.CanDeclareGlobalVar(vn)。
          2. 如果 vnDefinablefalse,抛出 TypeError 异常。
          3. 如果 declaredVarNames 中不包含 vn,则
            1. vn 添加到 declaredVarNames 中。
  11. 注意:如果 global object 是一个 ordinary object,则此算法步骤不会发生异常终止。然而,如果 global object 是一个 Proxy exotic object,它可能表现出导致后续步骤异常终止的行为。
  12. 注意:附录 B.3.2.2 在此处添加了额外的步骤。
  13. lexDeclarationsLexicallyScopedDeclarationsscript
  14. privateEnvnull
  15. lexDeclarations 的每个元素 d 执行
    1. 注意:词法声明的名称仅在此处实例化,但不会初始化。
    2. dBoundNames 的每个元素 dn 执行
      1. 如果 IsConstantDeclarationtrue,则
        1. 执行 ? env.CreateImmutableBinding(dn, true)。
      2. 否则,
        1. 执行 ? env.CreateMutableBinding(dn, false)。
  16. functionsToInitialize 的每个 Parse Node f 执行
    1. fnf 的唯一元素的 BoundNames
    2. foInstantiateFunctionObjectf,参数为 envprivateEnv
    3. 执行 ? env.CreateGlobalFunctionBinding(fn, fo, false)。
  17. declaredVarNames 的每个字符串 vn 执行
    1. 执行 ? env.CreateGlobalVarBinding(vn, false)。
  18. 返回 unused
注 2

早期错误16.1.1 中规定,防止函数/变量声明与 let/const/class 声明之间的名称冲突以及同一 脚本 中 let/const/class 绑定的重新声明。然而,跨多个 脚本 的此类冲突和重新声明会在 GlobalDeclarationInstantiation 期间被检测为运行时错误。如果检测到任何此类错误,则不会为脚本实例化任何绑定。然而,如果 全球对象 是通过 Proxy 异otic 对象 定义的,那么运行时对冲突声明的测试可能不可靠,导致 突然完成 和一些全局声明未被实例化。如果发生这种情况,脚本 的代码将不会被评估。

与显式的 var 或函数声明不同,直接在 全局对象 上创建的属性会导致全局绑定,这些绑定可能会被 let/const/class 声明遮蔽。

16.2 模块

语法

Module : ModuleBodyopt ModuleBody : ModuleItemList ModuleItemList : ModuleItem ModuleItemList ModuleItem ModuleItem : ImportDeclaration ExportDeclaration StatementListItem[~Yield, +Await, ~Return] ModuleExportName : IdentifierName StringLiteral

16.2.1 Module Semantics

16.2.1.1 Static Semantics: Early Errors

ModuleBody : ModuleItemList Note

The duplicate ExportedNames rule implies that multiple export default ExportDeclaration items within a ModuleBody is a Syntax Error. Additional error conditions relating to conflicting or duplicate declarations are checked during module linking prior to evaluation of a Module. If any such errors are detected the Module is not evaluated.

ModuleExportName : StringLiteral

16.2.1.2 Static Semantics: ImportedLocalNames ( importEntries )

The abstract operation ImportedLocalNames takes argument importEntries (a List of ImportEntry Records) and returns a List of Strings. It creates a List of all of the local name bindings defined by importEntries. It performs the following steps when called:

  1. Let localNames be a new empty List.
  2. For each ImportEntry Record i of importEntries, do
    1. Append i.[[LocalName]] to localNames.
  3. Return localNames.

16.2.1.3 Static Semantics: ModuleRequests

The syntax-directed operation ModuleRequests takes no arguments and returns a List of Strings. It is defined piecewise over the following productions:

Module : [empty]
  1. Return a new empty List.
ModuleItemList : ModuleItem
  1. Return ModuleRequests of ModuleItem.
ModuleItemList : ModuleItemList ModuleItem
  1. Let moduleNames be ModuleRequests of ModuleItemList.
  2. Let additionalNames be ModuleRequests of ModuleItem.
  3. For each String name of additionalNames, do
    1. If moduleNames does not contain name, then
      1. Append name to moduleNames.
  4. Return moduleNames.
ModuleItem : StatementListItem
  1. Return a new empty List.
ImportDeclaration : import ImportClause FromClause ;
  1. Return ModuleRequests of FromClause.
ModuleSpecifier : StringLiteral
  1. Return a List whose sole element is the SV of StringLiteral.
ExportDeclaration : export ExportFromClause FromClause ;
  1. Return the ModuleRequests of FromClause.
ExportDeclaration : export NamedExports ; export VariableStatement export Declaration export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. Return a new empty List.

16.2.1.4 Abstract Module Records

A Module Record encapsulates structural information about the imports and exports of a single module. This information is used to link the imports and exports of sets of connected modules. A Module Record includes four fields that are only used when evaluating a module.

For specification purposes Module Record values are values of the Record specification type and can be thought of as existing in a simple object-oriented hierarchy where Module Record is an abstract class with both abstract and concrete subclasses. This specification defines the abstract subclass named Cyclic Module Record and its concrete subclass named Source Text Module Record. Other specifications and implementations may define additional Module Record subclasses corresponding to alternative module definition facilities that they defined.

Module Record defines the fields listed in Table 41. All Module Definition subclasses include at least those fields. Module Record also defines the abstract method list in Table 42. All Module definition subclasses must provide concrete implementations of these abstract methods.

Table 41: Module Record Fields
Field Name Value Type Meaning
[[Realm]] a Realm Record The Realm within which this module was created.
[[Environment]] a Module Environment Record or empty The Environment Record containing the top level bindings for this module. This field is set when the module is linked.
[[Namespace]] an Object or empty The Module Namespace Object (28.3) if one has been created for this module.
[[HostDefined]] anything (default value is undefined) Field reserved for use by host environments that need to associate additional information with a module.
Table 42: Abstract Methods of Module Records
Method Purpose
LoadRequestedModules( [ hostDefined ] )

Prepares the module for linking by recursively loading all its dependencies, and returns a promise.

GetExportedNames([exportStarSet])

Return a list of all names that are either directly or indirectly exported from this module.

LoadRequestedModules must have completed successfully prior to invoking this method.

ResolveExport(exportName [, resolveSet])

Return the binding of a name exported by this module. Bindings are represented by a ResolvedBinding Record, of the form { [[Module]]: Module Record, [[BindingName]]: String | namespace }. If the export is a Module Namespace Object without a direct binding in any module, [[BindingName]] will be set to namespace. Return null if the name cannot be resolved, or ambiguous if multiple bindings were found.

Each time this operation is called with a specific exportName, resolveSet pair as arguments it must return the same result.

LoadRequestedModules must have completed successfully prior to invoking this method.

Link()

Prepare the module for evaluation by transitively resolving all module dependencies and creating a Module Environment Record.

LoadRequestedModules must have completed successfully prior to invoking this method.

Evaluate()

Returns a promise for the evaluation of this module and its dependencies, resolving on successful evaluation or if it has already been evaluated successfully, and rejecting for an evaluation error or if it has already been evaluated unsuccessfully. If the promise is rejected, hosts are expected to handle the promise rejection and rethrow the evaluation error.

Link must have completed successfully prior to invoking this method.

16.2.1.5 Cyclic Module Records

A Cyclic Module Record is used to represent information about a module that can participate in dependency cycles with other modules that are subclasses of the Cyclic Module Record type. Module Records that are not subclasses of the Cyclic Module Record type must not participate in dependency cycles with Source Text Module Records.

In addition to the fields defined in Table 41 Cyclic Module Records have the additional fields listed in Table 43

Table 43: Additional Fields of Cyclic Module Records
Field Name Value Type Meaning
[[Status]] new, unlinked, linking, linked, evaluating, evaluating-async, or evaluated Initially new. Transitions to unlinked, linking, linked, evaluating, possibly evaluating-async, evaluated (in that order) as the module progresses throughout its lifecycle. evaluating-async indicates this module is queued to execute on completion of its asynchronous dependencies or it is a module whose [[HasTLA]] field is true that has been executed and is pending top-level completion.
[[EvaluationError]] a throw completion or empty A throw completion representing the exception that occurred during evaluation. undefined if no exception occurred or if [[Status]] is not evaluated.
[[DFSIndex]] an integer or empty Auxiliary field used during Link and Evaluate only. If [[Status]] is either linking or evaluating, this non-negative number records the point at which the module was first visited during the depth-first traversal of the dependency graph.
[[DFSAncestorIndex]] an integer or empty Auxiliary field used during Link and Evaluate only. If [[Status]] is either linking or evaluating, this is either the module's own [[DFSIndex]] or that of an "earlier" module in the same strongly connected component.
[[RequestedModules]] a List of Strings A List of all the ModuleSpecifier strings used by the module represented by this record to request the importation of a module. The List is in source text occurrence order.
[[LoadedModules]] a List of Records with fields [[Specifier]] (a String) and [[Module]] (a Module Record) A map from the specifier strings used by the module represented by this record to request the importation of a module to the resolved Module Record. The list does not contain two different Records with the same [[Specifier]].
[[CycleRoot]] a Cyclic Module Record or empty The first visited module of the cycle, the root DFS ancestor of the strongly connected component. For a module not in a cycle, this would be the module itself. Once Evaluate has completed, a module's [[DFSAncestorIndex]] is the [[DFSIndex]] of its [[CycleRoot]].
[[HasTLA]] a Boolean Whether this module is individually asynchronous (for example, if it's a Source Text Module Record containing a top-level await). Having an asynchronous dependency does not mean this field is true. This field must not change after the module is parsed.
[[AsyncEvaluation]] a Boolean Whether this module is either itself asynchronous or has an asynchronous dependency. Note: The order in which this field is set is used to order queued executions, see 16.2.1.5.3.4.
[[TopLevelCapability]] a PromiseCapability Record or empty If this module is the [[CycleRoot]] of some cycle, and Evaluate() was called on some module in that cycle, this field contains the PromiseCapability Record for that entire evaluation. It is used to settle the Promise object that is returned from the Evaluate() abstract method. This field will be empty for any dependencies of that module, unless a top-level Evaluate() has been initiated for some of those dependencies.
[[AsyncParentModules]] a List of Cyclic Module Records If this module or a dependency has [[HasTLA]] true, and execution is in progress, this tracks the parent importers of this module for the top-level execution job. These parent modules will not start executing before this module has successfully completed execution.
[[PendingAsyncDependencies]] an integer or empty If this module has any asynchronous dependencies, this tracks the number of asynchronous dependency modules remaining to execute for this module. A module with asynchronous dependencies will be executed when this field reaches 0 and there are no execution errors.

In addition to the methods defined in Table 42 Cyclic Module Records have the additional methods listed in Table 44

Table 44: Additional Abstract Methods of Cyclic Module Records
Method Purpose
InitializeEnvironment() Initialize the Environment Record of the module, including resolving all imported bindings, and create the module's execution context.
ExecuteModule( [ promiseCapability ] ) Evaluate the module's code within its execution context. If this module has true in [[HasTLA]], then a PromiseCapability Record is passed as an argument, and the method is expected to resolve or reject the given capability. In this case, the method must not throw an exception, but instead reject the PromiseCapability Record if necessary.

A GraphLoadingState Record is a Record that contains information about the loading process of a module graph. It's used to continue loading after a call to HostLoadImportedModule. Each GraphLoadingState Record has the fields defined in Table 45:

Table 45: GraphLoadingState Record Fields
Field Name Value Type Meaning
[[PromiseCapability]] a PromiseCapability Record The promise to resolve when the loading process finishes.
[[IsLoading]] a Boolean It is true if the loading process has not finished yet, neither successfully nor with an error.
[[PendingModulesCount]] a non-negative integer It tracks the number of pending HostLoadImportedModule calls.
[[Visited]] a List of Cyclic Module Records It is a list of the Cyclic Module Records that have been already loaded by the current loading process, to avoid infinite loops with circular dependencies.
[[HostDefined]] anything (default value is empty) It contains host-defined data to pass from the LoadRequestedModules caller to HostLoadImportedModule.

16.2.1.5.1 LoadRequestedModules ( [ hostDefined ] )

The LoadRequestedModules concrete method of a Cyclic Module Record module takes optional argument hostDefined (anything) and returns a Promise. It populates the [[LoadedModules]] of all the Module Records in the dependency graph of module (most of the work is done by the auxiliary function InnerModuleLoading). It takes an optional hostDefined parameter that is passed to the HostLoadImportedModule hook. It performs the following steps when called:

  1. If hostDefined is not present, let hostDefined be empty.
  2. Let pc be ! NewPromiseCapability(%Promise%).
  3. Let state be the GraphLoadingState Record { [[IsLoading]]: true, [[PendingModulesCount]]: 1, [[Visited]]: « », [[PromiseCapability]]: pc, [[HostDefined]]: hostDefined }.
  4. Perform InnerModuleLoading(state, module).
  5. Return pc.[[Promise]].
Note
The hostDefined parameter can be used to pass additional information necessary to fetch the imported modules. It is used, for example, by HTML to set the correct fetch destination for <link rel="preload" as="..."> tags. import() expressions never set the hostDefined parameter.

16.2.1.5.1.1 InnerModuleLoading ( state, module )

The abstract operation InnerModuleLoading takes arguments state (a GraphLoadingState Record) and module (a Module Record) and returns unused. It is used by LoadRequestedModules to recursively perform the actual loading process for module's dependency graph. It performs the following steps when called:

  1. Assert: state.[[IsLoading]] is true.
  2. If module is a Cyclic Module Record, module.[[Status]] is new, and state.[[Visited]] does not contain module, then
    1. Append module to state.[[Visited]].
    2. Let requestedModulesCount be the number of elements in module.[[RequestedModules]].
    3. Set state.[[PendingModulesCount]] to state.[[PendingModulesCount]] + requestedModulesCount.
    4. For each String required of module.[[RequestedModules]], do
      1. If module.[[LoadedModules]] contains a Record whose [[Specifier]] is required, then
        1. Let record be that Record.
        2. Perform InnerModuleLoading(state, record.[[Module]]).
      2. Else,
        1. Perform HostLoadImportedModule(module, required, state.[[HostDefined]], state).
        2. NOTE: HostLoadImportedModule will call FinishLoadingImportedModule, which re-enters the graph loading process through ContinueModuleLoading.
      3. If state.[[IsLoading]] is false, return unused.
  3. Assert: state.[[PendingModulesCount]] ≥ 1.
  4. Set state.[[PendingModulesCount]] to state.[[PendingModulesCount]] - 1.
  5. If state.[[PendingModulesCount]] = 0, then
    1. Set state.[[IsLoading]] to false.
    2. For each Cyclic Module Record loaded of state.[[Visited]], do
      1. If loaded.[[Status]] is new, set loaded.[[Status]] to unlinked.
    3. Perform ! Call(state.[[PromiseCapability]].[[Resolve]], undefined, « undefined »).
  6. Return unused.

16.2.1.5.1.2 ContinueModuleLoading ( state, moduleCompletion )

The abstract operation ContinueModuleLoading takes arguments state (a GraphLoadingState Record) and moduleCompletion (either a normal completion containing a Module Record or a throw completion) and returns unused. It is used to re-enter the loading process after a call to HostLoadImportedModule. It performs the following steps when called:

  1. If state.[[IsLoading]] is false, return unused.
  2. If moduleCompletion is a normal completion, then
    1. Perform InnerModuleLoading(state, moduleCompletion.[[Value]]).
  3. Else,
    1. Set state.[[IsLoading]] to false.
    2. Perform ! Call(state.[[PromiseCapability]].[[Reject]], undefined, « moduleCompletion.[[Value]] »).
  4. Return unused.

16.2.1.5.2 Link ( )

The Link concrete method of a Cyclic Module Record module takes no arguments and returns either a normal completion containing unused or a throw completion. On success, Link transitions this module's [[Status]] from unlinked to linked. On failure, an exception is thrown and this module's [[Status]] remains unlinked. (Most of the work is done by the auxiliary function InnerModuleLinking.) It performs the following steps when called:

  1. Assert: module.[[Status]] is one of unlinked, linked, evaluating-async, or evaluated.
  2. Let stack be a new empty List.
  3. Let result be Completion(InnerModuleLinking(module, stack, 0)).
  4. If result is an abrupt completion, then
    1. For each Cyclic Module Record m of stack, do
      1. Assert: m.[[Status]] is linking.
      2. Set m.[[Status]] to unlinked.
    2. Assert: module.[[Status]] is unlinked.
    3. Return ? result.
  5. Assert: module.[[Status]] is one of linked, evaluating-async, or evaluated.
  6. Assert: stack is empty.
  7. Return unused.

16.2.1.5.2.1 InnerModuleLinking ( module, stack, index )

The abstract operation InnerModuleLinking takes arguments module (a Module Record), stack (a List of Cyclic Module Records), and index (a non-negative integer) and returns either a normal completion containing a non-negative integer or a throw completion. It is used by Link to perform the actual linking process for module, as well as recursively on all other modules in the dependency graph. The stack and index parameters, as well as a module's [[DFSIndex]] and [[DFSAncestorIndex]] fields, keep track of the depth-first search (DFS) traversal. In particular, [[DFSAncestorIndex]] is used to discover strongly connected components (SCCs), such that all modules in an SCC transition to linked together. It performs the following steps when called:

  1. If module is not a Cyclic Module Record, then
    1. Perform ? module.Link().
    2. Return index.
  2. If module.[[Status]] is one of linking, linked, evaluating-async, or evaluated, then
    1. Return index.
  3. Assert: module.[[Status]] is unlinked.
  4. Set module.[[Status]] to linking.
  5. Set module.[[DFSIndex]] to index.
  6. Set module.[[DFSAncestorIndex]] to index.
  7. Set index to index + 1.
  8. Append module to stack.
  9. For each String required of module.[[RequestedModules]], do
    1. Let requiredModule be GetImportedModule(module, required).
    2. Set index to ? InnerModuleLinking(requiredModule, stack, index).
    3. If requiredModule is a Cyclic Module Record, then
      1. Assert: requiredModule.[[Status]] is one of linking, linked, evaluating-async, or evaluated.
      2. Assert: requiredModule.[[Status]] is linking if and only if stack contains requiredModule.
      3. If requiredModule.[[Status]] is linking, then
        1. Set module.[[DFSAncestorIndex]] to min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]).
  10. Perform ? module.InitializeEnvironment().
  11. Assert: module occurs exactly once in stack.
  12. Assert: module.[[DFSAncestorIndex]]module.[[DFSIndex]].
  13. If module.[[DFSAncestorIndex]] = module.[[DFSIndex]], then
    1. Let done be false.
    2. Repeat, while done is false,
      1. Let requiredModule be the last element of stack.
      2. Remove the last element of stack.
      3. Assert: requiredModule is a Cyclic Module Record.
      4. Set requiredModule.[[Status]] to linked.
      5. If requiredModule and module are the same Module Record, set done to true.
  14. Return index.

16.2.1.5.3 Evaluate ( )

The Evaluate concrete method of a Cyclic Module Record module takes no arguments and returns a Promise. Evaluate transitions this module's [[Status]] from linked to either evaluating-async or evaluated. The first time it is called on a module in a given strongly connected component, Evaluate creates and returns a Promise which resolves when the module has finished evaluating. This Promise is stored in the [[TopLevelCapability]] field of the [[CycleRoot]] for the component. Future invocations of Evaluate on any module in the component return the same Promise. (Most of the work is done by the auxiliary function InnerModuleEvaluation.) It performs the following steps when called:

  1. Assert: This call to Evaluate is not happening at the same time as another call to Evaluate within the surrounding agent.
  2. Assert: module.[[Status]] is one of linked, evaluating-async, or evaluated.
  3. If module.[[Status]] is either evaluating-async or evaluated, set module to module.[[CycleRoot]].
  4. If module.[[TopLevelCapability]] is not empty, then
    1. Return module.[[TopLevelCapability]].[[Promise]].
  5. Let stack be a new empty List.
  6. Let capability be ! NewPromiseCapability(%Promise%).
  7. Set module.[[TopLevelCapability]] to capability.
  8. Let result be Completion(InnerModuleEvaluation(module, stack, 0)).
  9. If result is an abrupt completion, then
    1. For each Cyclic Module Record m of stack, do
      1. Assert: m.[[Status]] is evaluating.
      2. Set m.[[Status]] to evaluated.
      3. Set m.[[EvaluationError]] to result.
    2. Assert: module.[[Status]] is evaluated.
    3. Assert: module.[[EvaluationError]] is result.
    4. Perform ! Call(capability.[[Reject]], undefined, « result.[[Value]] »).
  10. Else,
    1. Assert: module.[[Status]] is either evaluating-async or evaluated.
    2. Assert: module.[[EvaluationError]] is empty.
    3. If module.[[AsyncEvaluation]] is false, then
      1. Assert: module.[[Status]] is evaluated.
      2. Perform ! Call(capability.[[Resolve]], undefined, « undefined »).
    4. Assert: stack is empty.
  11. Return capability.[[Promise]].

16.2.1.5.3.1 InnerModuleEvaluation ( module, stack, index )

The abstract operation InnerModuleEvaluation takes arguments module (a Module Record), stack (a List of Cyclic Module Records), and index (a non-negative integer) and returns either a normal completion containing a non-negative integer or a throw completion. It is used by Evaluate to perform the actual evaluation process for module, as well as recursively on all other modules in the dependency graph. The stack and index parameters, as well as module's [[DFSIndex]] and [[DFSAncestorIndex]] fields, are used the same way as in InnerModuleLinking. It performs the following steps when called:

  1. If module is not a Cyclic Module Record, then
    1. Let promise be ! module.Evaluate().
    2. Assert: promise.[[PromiseState]] is not pending.
    3. If promise.[[PromiseState]] is rejected, then
      1. Return ThrowCompletion(promise.[[PromiseResult]]).
    4. Return index.
  2. If module.[[Status]] is either evaluating-async or evaluated, then
    1. If module.[[EvaluationError]] is empty, return index.
    2. Otherwise, return ? module.[[EvaluationError]].
  3. If module.[[Status]] is evaluating, return index.
  4. Assert: module.[[Status]] is linked.
  5. Set module.[[Status]] to evaluating.
  6. Set module.[[DFSIndex]] to index.
  7. Set module.[[DFSAncestorIndex]] to index.
  8. Set module.[[PendingAsyncDependencies]] to 0.
  9. Set index to index + 1.
  10. Append module to stack.
  11. For each String required of module.[[RequestedModules]], do
    1. Let requiredModule be GetImportedModule(module, required).
    2. Set index to ? InnerModuleEvaluation(requiredModule, stack, index).
    3. If requiredModule is a Cyclic Module Record, then
      1. Assert: requiredModule.[[Status]] is one of evaluating, evaluating-async, or evaluated.
      2. Assert: requiredModule.[[Status]] is evaluating if and only if stack contains requiredModule.
      3. If requiredModule.[[Status]] is evaluating, then
        1. Set module.[[DFSAncestorIndex]] to min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]).
      4. Else,
        1. Set requiredModule to requiredModule.[[CycleRoot]].
        2. Assert: requiredModule.[[Status]] is either evaluating-async or evaluated.
        3. If requiredModule.[[EvaluationError]] is not empty, return ? requiredModule.[[EvaluationError]].
      5. If requiredModule.[[AsyncEvaluation]] is true, then
        1. Set module.[[PendingAsyncDependencies]] to module.[[PendingAsyncDependencies]] + 1.
        2. Append module to requiredModule.[[AsyncParentModules]].
  12. If module.[[PendingAsyncDependencies]] > 0 or module.[[HasTLA]] is true, then
    1. Assert: module.[[AsyncEvaluation]] is false and was never previously set to true.
    2. Set module.[[AsyncEvaluation]] to true.
    3. NOTE: The order in which module records have their [[AsyncEvaluation]] fields transition to true is significant. (See 16.2.1.5.3.4.)
    4. If module.[[PendingAsyncDependencies]] = 0, perform ExecuteAsyncModule(module).
  13. Else,
    1. Perform ? module.ExecuteModule().
  14. Assert: module occurs exactly once in stack.
  15. Assert: module.[[DFSAncestorIndex]]module.[[DFSIndex]].
  16. If module.[[DFSAncestorIndex]] = module.[[DFSIndex]], then
    1. Let done be false.
    2. Repeat, while done is false,
      1. Let requiredModule be the last element of stack.
      2. Remove the last element of stack.
      3. Assert: requiredModule is a Cyclic Module Record.
      4. If requiredModule.[[AsyncEvaluation]] is false, set requiredModule.[[Status]] to evaluated.
      5. Otherwise, set requiredModule.[[Status]] to evaluating-async.
      6. If requiredModule and module are the same Module Record, set done to true.
      7. Set requiredModule.[[CycleRoot]] to module.
  17. Return index.
Note 1

A module is evaluating while it is being traversed by InnerModuleEvaluation. A module is evaluated on execution completion or evaluating-async during execution if its [[HasTLA]] field is true or if it has asynchronous dependencies.

Note 2

Any modules depending on a module of an asynchronous cycle when that cycle is not evaluating will instead depend on the execution of the root of the cycle via [[CycleRoot]]. This ensures that the cycle state can be treated as a single strongly connected component through its root module state.

16.2.1.5.3.2 ExecuteAsyncModule ( module )

The abstract operation ExecuteAsyncModule takes argument module (a Cyclic Module Record) and returns unused. It performs the following steps when called:

  1. Assert: module.[[Status]] is either evaluating or evaluating-async.
  2. Assert: module.[[HasTLA]] is true.
  3. Let capability be ! NewPromiseCapability(%Promise%).
  4. Let fulfilledClosure be a new Abstract Closure with no parameters that captures module and performs the following steps when called:
    1. Perform AsyncModuleExecutionFulfilled(module).
    2. Return undefined.
  5. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
  6. Let rejectedClosure be a new Abstract Closure with parameters (error) that captures module and performs the following steps when called:
    1. Perform AsyncModuleExecutionRejected(module, error).
    2. Return undefined.
  7. Let onRejected be CreateBuiltinFunction(rejectedClosure, 0, "", « »).
  8. Perform PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
  9. Perform ! module.ExecuteModule(capability).
  10. Return unused.

16.2.1.5.3.3 GatherAvailableAncestors ( module, execList )

The abstract operation GatherAvailableAncestors takes arguments module (a Cyclic Module Record) and execList (a List of Cyclic Module Records) and returns unused. It performs the following steps when called:

  1. For each Cyclic Module Record m of module.[[AsyncParentModules]], do
    1. If execList does not contain m and m.[[CycleRoot]].[[EvaluationError]] is empty, then
      1. Assert: m.[[Status]] is evaluating-async.
      2. Assert: m.[[EvaluationError]] is empty.
      3. Assert: m.[[AsyncEvaluation]] is true.
      4. Assert: m.[[PendingAsyncDependencies]] > 0.
      5. Set m.[[PendingAsyncDependencies]] to m.[[PendingAsyncDependencies]] - 1.
      6. If m.[[PendingAsyncDependencies]] = 0, then
        1. Append m to execList.
        2. If m.[[HasTLA]] is false, perform GatherAvailableAncestors(m, execList).
  2. Return unused.
Note

When an asynchronous execution for a root module is fulfilled, this function determines the list of modules which are able to synchronously execute together on this completion, populating them in execList.

16.2.1.5.3.4 AsyncModuleExecutionFulfilled ( module )

The abstract operation AsyncModuleExecutionFulfilled takes argument module (a Cyclic Module Record) and returns unused. It performs the following steps when called:

  1. If module.[[Status]] is evaluated, then
    1. Assert: module.[[EvaluationError]] is not empty.
    2. Return unused.
  2. Assert: module.[[Status]] is evaluating-async.
  3. Assert: module.[[AsyncEvaluation]] is true.
  4. Assert: module.[[EvaluationError]] is empty.
  5. Set module.[[AsyncEvaluation]] to false.
  6. Set module.[[Status]] to evaluated.
  7. If module.[[TopLevelCapability]] is not empty, then
    1. Assert: module.[[CycleRoot]] is module.
    2. Perform ! Call(module.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »).
  8. Let execList be a new empty List.
  9. Perform GatherAvailableAncestors(module, execList).
  10. Let sortedExecList be a List whose elements are the elements of execList, in the order in which they had their [[AsyncEvaluation]] fields set to true in InnerModuleEvaluation.
  11. Assert: All elements of sortedExecList have their [[AsyncEvaluation]] field set to true, [[PendingAsyncDependencies]] field set to 0, and [[EvaluationError]] field set to empty.
  12. For each Cyclic Module Record m of sortedExecList, do
    1. If m.[[Status]] is evaluated, then
      1. Assert: m.[[EvaluationError]] is not empty.
    2. Else if m.[[HasTLA]] is true, then
      1. Perform ExecuteAsyncModule(m).
    3. Else,
      1. Let result be m.ExecuteModule().
      2. If result is an abrupt completion, then
        1. Perform AsyncModuleExecutionRejected(m, result.[[Value]]).
      3. Else,
        1. Set m.[[Status]] to evaluated.
        2. If m.[[TopLevelCapability]] is not empty, then
          1. Assert: m.[[CycleRoot]] is m.
          2. Perform ! Call(m.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »).
  13. Return unused.

16.2.1.5.3.5 AsyncModuleExecutionRejected ( module, error )

The abstract operation AsyncModuleExecutionRejected takes arguments module (a Cyclic Module Record) and error (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. If module.[[Status]] is evaluated, then
    1. Assert: module.[[EvaluationError]] is not empty.
    2. Return unused.
  2. Assert: module.[[Status]] is evaluating-async.
  3. Assert: module.[[AsyncEvaluation]] is true.
  4. Assert: module.[[EvaluationError]] is empty.
  5. Set module.[[EvaluationError]] to ThrowCompletion(error).
  6. Set module.[[Status]] to evaluated.
  7. For each Cyclic Module Record m of module.[[AsyncParentModules]], do
    1. Perform AsyncModuleExecutionRejected(m, error).
  8. If module.[[TopLevelCapability]] is not empty, then
    1. Assert: module.[[CycleRoot]] is module.
    2. Perform ! Call(module.[[TopLevelCapability]].[[Reject]], undefined, « error »).
  9. Return unused.

16.2.1.5.4 Example Cyclic Module Record Graphs

This non-normative section gives a series of examples of the linking and evaluation of a few common module graphs, with a specific focus on how errors can occur.

First consider the following simple module graph:

Figure 2: A simple module graph
A module graph in which module A depends on module B, and module B depends on module C

Let's first assume that there are no error conditions. When a host first calls A.LoadRequestedModules(), this will complete successfully by assumption, and recursively load the dependencies of B and C as well (respectively, C and none), and then set A.[[Status]] = B.[[Status]] = C.[[Status]] = unlinked. Then, when the host calls A.Link(), it will complete successfully (again by assumption) such that A.[[Status]] = B.[[Status]] = C.[[Status]] = linked. These preparatory steps can be performed at any time. Later, when the host is ready to incur any possible side effects of the modules, it can call A.Evaluate(), which will complete successfully, returning a Promise resolving to undefined (again by assumption), recursively having evaluated first C and then B. Each module's [[Status]] at this point will be evaluated.

Consider then cases involving linking errors, after a successful call to A.LoadRequestedModules(). If InnerModuleLinking of C succeeds but, thereafter, fails for B, for example because it imports something that C does not provide, then the original A.Link() will fail, and both A and B's [[Status]] remain unlinked. C's [[Status]] has become linked, though.

Finally, consider a case involving evaluation errors after a successful call to Link(). If InnerModuleEvaluation of C succeeds but, thereafter, fails for B, for example because B contains code that throws an exception, then the original A.Evaluate() will fail, returning a rejected Promise. The resulting exception will be recorded in both A and B's [[EvaluationError]] fields, and their [[Status]] will become evaluated. C will also become evaluated but, in contrast to A and B, will remain without an [[EvaluationError]], as it successfully completed evaluation. Storing the exception ensures that any time a host tries to reuse A or B by calling their Evaluate() method, it will encounter the same exception. (Hosts are not required to reuse Cyclic Module Records; similarly, hosts are not required to expose the exception objects thrown by these methods. However, the specification enables such uses.)

Now consider a different type of error condition:

Figure 3: A module graph with an unresolvable module
A module graph in which module A depends on a missing (unresolvable) module, represented by ???

In this scenario, module A declares a dependency on some other module, but no Module Record exists for that module, i.e. HostLoadImportedModule calls FinishLoadingImportedModule with an exception when asked for it. This could occur for a variety of reasons, such as the corresponding resource not existing, or the resource existing but ParseModule returning some errors when trying to parse the resulting source text. Hosts can choose to expose the cause of failure via the completion they pass to FinishLoadingImportedModule. In any case, this exception causes a loading failure, which results in A's [[Status]] remaining new.

The difference here between loading, linking and evaluation errors is due to the following characteristic:

  • Evaluation must be only performed once, as it can cause side effects; it is thus important to remember whether evaluation has already been performed, even if unsuccessfully. (In the error case, it makes sense to also remember the exception because otherwise subsequent Evaluate() calls would have to synthesize a new one.)
  • Linking, on the other hand, is side-effect-free, and thus even if it fails, it can be retried at a later time with no issues.
  • Loading closely interacts with the host, and it may be desiderable for some of them to allow users to retry failed loads (for example, if the failure is caused by temporarily bad network conditions).

Now, consider a module graph with a cycle:

Figure 4: A cyclic module graph
A module graph in which module A depends on module B and C, but module B also depends on module A

Here we assume that the entry point is module A, so that the host proceeds by calling A.LoadRequestedModules(), which performs InnerModuleLoading on A. This in turn calls InnerModuleLoading on B and C. Because of the cycle, this again triggers InnerModuleLoading on A, but at this point it is a no-op since A's dependencies loading has already been triggered during this LoadRequestedModules process. When all the modules in the graph have been successfully loaded, their [[Status]] transitions from new to unlinked at the same time.

Then the host proceeds by calling A.Link(), which performs InnerModuleLinking on A. This in turn calls InnerModuleLinking on B. Because of the cycle, this again triggers InnerModuleLinking on A, but at this point it is a no-op since A.[[Status]] is already linking. B.[[Status]] itself remains linking when control gets back to A and InnerModuleLinking is triggered on C. After this returns with C.[[Status]] being linked, both A and B transition from linking to linked together; this is by design, since they form a strongly connected component. It's possible to transition the status of modules in the same SCC at the same time because during this phase the module graph is traversed with a depth-first search.

An analogous story occurs for the evaluation phase of a cyclic module graph, in the success case.

Now consider a case where A has a linking error; for example, it tries to import a binding from C that does not exist. In that case, the above steps still occur, including the early return from the second call to InnerModuleLinking on A. However, once we unwind back to the original InnerModuleLinking on A, it fails during InitializeEnvironment, namely right after C.ResolveExport(). The thrown SyntaxError exception propagates up to A.Link, which resets all modules that are currently on its stack (these are always exactly the modules that are still linking). Hence both A and B become unlinked. Note that C is left as linked.

Alternatively, consider a case where A has an evaluation error; for example, its source code throws an exception. In that case, the evaluation-time analog of the above steps still occurs, including the early return from the second call to InnerModuleEvaluation on A. However, once we unwind back to the original InnerModuleEvaluation on A, it fails by assumption. The exception thrown propagates up to A.Evaluate(), which records the error in all modules that are currently on its stack (i.e., the modules that are still evaluating) as well as via [[AsyncParentModules]], which form a chain for modules which contain or depend on top-level await through the whole dependency graph through the AsyncModuleExecutionRejected algorithm. Hence both A and B become evaluated and the exception is recorded in both A and B's [[EvaluationError]] fields, while C is left as evaluated with no [[EvaluationError]].

Lastly, consider a module graph with a cycle, where all modules complete asynchronously:

Figure 5: An asynchronous cyclic module graph
A module graph in which module A depends on module B and C, module B depends on module D, module C depends on module D and E, and module D depends on module A

Loading and linking happen as before, and all modules end up with [[Status]] set to linked.

Calling A.Evaluate() calls InnerModuleEvaluation on A, B, and D, which all transition to evaluating. Then InnerModuleEvaluation is called on A again, which is a no-op because it is already evaluating. At this point, D.[[PendingAsyncDependencies]] is 0, so ExecuteAsyncModule(D) is called and we call D.ExecuteModule with a new PromiseCapability tracking the asynchronous execution of D. We unwind back to the InnerModuleEvaluation on B, setting B.[[PendingAsyncDependencies]] to 1 and B.[[AsyncEvaluation]] to true. We unwind back to the original InnerModuleEvaluation on A, setting A.[[PendingAsyncDependencies]] to 1. In the next iteration of the loop over A's dependencies, we call InnerModuleEvaluation on C and thus on D (again a no-op) and E. As E has no dependencies and is not part of a cycle, we call ExecuteAsyncModule(E) in the same manner as D and E is immediately removed from the stack. We unwind once more to the original InnerModuleEvaluation on A, setting C.[[AsyncEvaluation]] to true. Now we finish the loop over A's dependencies, set A.[[AsyncEvaluation]] to true, and remove the entire strongly connected component from the stack, transitioning all of the modules to evaluating-async at once. At this point, the fields of the modules are as given in Table 46.

Table 46: Module fields after the initial Evaluate() call
Module [[DFSIndex]] [[DFSAncestorIndex]] [[Status]] [[AsyncEvaluation]] [[AsyncParentModules]] [[PendingAsyncDependencies]]
A 0 0 evaluating-async true « » 2 (B and C)
B 1 0 evaluating-async true « A » 1 (D)
C 2 0 evaluating-async true « A » 2 (D and E)
D 3 0 evaluating-async true « B, C » 0
E 4 4 evaluating-async true « C » 0

Let us assume that E finishes executing first. When that happens, AsyncModuleExecutionFulfilled is called, E.[[Status]] is set to evaluated and C.[[PendingAsyncDependencies]] is decremented to become 1. The fields of the updated modules are as given in Table 47.

Table 47: Module fields after module E finishes executing
Module [[DFSIndex]] [[DFSAncestorIndex]] [[Status]] [[AsyncEvaluation]] [[AsyncParentModules]] [[PendingAsyncDependencies]]
C 2 0 evaluating-async true « A » 1 (D)
E 4 4 evaluated true « C » 0

D is next to finish (as it was the only module that was still executing). When that happens, AsyncModuleExecutionFulfilled is called again and D.[[Status]] is set to evaluated. Then B.[[PendingAsyncDependencies]] is decremented to become 0, ExecuteAsyncModule is called on B, and it starts executing. C.[[PendingAsyncDependencies]] is also decremented to become 0, and C starts executing (potentially in parallel to B if B contains an await). The fields of the updated modules are as given in Table 48.

Table 48: Module fields after module D finishes executing
Module [[DFSIndex]] [[DFSAncestorIndex]] [[Status]] [[AsyncEvaluation]] [[AsyncParentModules]] [[PendingAsyncDependencies]]
B 1 0 evaluating-async true « A » 0
C 2 0 evaluating-async true « A » 0
D 3 0 evaluated true « B, C » 0

Let us assume that C finishes executing next. When that happens, AsyncModuleExecutionFulfilled is called again, C.[[Status]] is set to evaluated and A.[[PendingAsyncDependencies]] is decremented to become 1. The fields of the updated modules are as given in Table 49.

Table 49: Module fields after module C finishes executing
Module [[DFSIndex]] [[DFSAncestorIndex]] [[Status]] [[AsyncEvaluation]] [[AsyncParentModules]] [[PendingAsyncDependencies]]
A 0 0 evaluating-async true « » 1 (B)
C 2 0 evaluated true « A » 0

Then, B finishes executing. When that happens, AsyncModuleExecutionFulfilled is called again and B.[[Status]] is set to evaluated. A.[[PendingAsyncDependencies]] is decremented to become 0, so ExecuteAsyncModule is called and it starts executing. The fields of the updated modules are as given in Table 50.

Table 50: Module fields after module B finishes executing
Module [[DFSIndex]] [[DFSAncestorIndex]] [[Status]] [[AsyncEvaluation]] [[AsyncParentModules]] [[PendingAsyncDependencies]]
A 0 0 evaluating-async true « » 0
B 1 0 evaluated true « A » 0

Finally, A finishes executing. When that happens, AsyncModuleExecutionFulfilled is called again and A.[[Status]] is set to evaluated. At this point, the Promise in A.[[TopLevelCapability]] (which was returned from A.Evaluate()) is resolved, and this concludes the handling of this module graph. The fields of the updated module are as given in Table 51.

Table 51: Module fields after module A finishes executing
Module [[DFSIndex]] [[DFSAncestorIndex]] [[Status]] [[AsyncEvaluation]] [[AsyncParentModules]] [[PendingAsyncDependencies]]
A 0 0 evaluated true « » 0

Alternatively, consider a failure case where C fails execution and returns an error before B has finished executing. When that happens, AsyncModuleExecutionRejected is called, which sets C.[[Status]] to evaluated and C.[[EvaluationError]] to the error. It then propagates this error to all of the AsyncParentModules by performing AsyncModuleExecutionRejected on each of them. The fields of the updated modules are as given in Table 52.

Table 52: Module fields after module C finishes with an error
Module [[DFSIndex]] [[DFSAncestorIndex]] [[Status]] [[AsyncEvaluation]] [[AsyncParentModules]] [[PendingAsyncDependencies]] [[EvaluationError]]
A 0 0 evaluated true « » 1 (B) empty
C 2 1 evaluated true « A » 0 C's evaluation error

A will be rejected with the same error as C since C will call AsyncModuleExecutionRejected on A with C's error. A.[[Status]] is set to evaluated. At this point the Promise in A.[[TopLevelCapability]] (which was returned from A.Evaluate()) is rejected. The fields of the updated module are as given in Table 53.

Table 53: Module fields after module A is rejected
Module [[DFSIndex]] [[DFSAncestorIndex]] [[Status]] [[AsyncEvaluation]] [[AsyncParentModules]] [[PendingAsyncDependencies]] [[EvaluationError]]
A 0 0 evaluated true « » 0 C's Evaluation Error

Then, B finishes executing without an error. When that happens, AsyncModuleExecutionFulfilled is called again and B.[[Status]] is set to evaluated. GatherAvailableAncestors is called on B. However, A.[[CycleRoot]] is A which has an evaluation error, so it will not be added to the returned sortedExecList and AsyncModuleExecutionFulfilled will return without further processing. Any future importer of B will resolve the rejection of B.[[CycleRoot]].[[EvaluationError]] from the evaluation error from C that was set on the cycle root A. The fields of the updated modules are as given in Table 54.

Table 54: Module fields after module B finishes executing in an erroring graph
Module [[DFSIndex]] [[DFSAncestorIndex]] [[Status]] [[AsyncEvaluation]] [[AsyncParentModules]] [[PendingAsyncDependencies]] [[EvaluationError]]
A 0 0 evaluated true « » 0 C's Evaluation Error
B 1 0 evaluated true « A » 0 empty

16.2.1.6 Source Text Module Records

A Source Text Module Record is used to represent information about a module that was defined from ECMAScript source text (11) that was parsed using the goal symbol Module. Its fields contain digested information about the names that are imported and exported by the module, and its concrete methods use these digests to link and evaluate the module.

A Source Text Module Record can exist in a module graph with other subclasses of the abstract Module Record type, and can participate in cycles with other subclasses of the Cyclic Module Record type.

In addition to the fields defined in Table 43, Source Text Module Records have the additional fields listed in Table 55. Each of these fields is initially set in ParseModule.

Table 55: Additional Fields of Source Text Module Records
Field Name Value Type Meaning
[[ECMAScriptCode]] a Parse Node The result of parsing the source text of this module using Module as the goal symbol.
[[Context]] an ECMAScript code execution context or empty The execution context associated with this module. It is empty until the module's environment has been initialized.
[[ImportMeta]] an Object or empty An object exposed through the import.meta meta property. It is empty until it is accessed by ECMAScript code.
[[ImportEntries]] a List of ImportEntry Records A List of ImportEntry records derived from the code of this module.
[[LocalExportEntries]] a List of ExportEntry Records A List of ExportEntry records derived from the code of this module that correspond to declarations that occur within the module.
[[IndirectExportEntries]] a List of ExportEntry Records A List of ExportEntry records derived from the code of this module that correspond to reexported imports that occur within the module or exports from export * as namespace declarations.
[[StarExportEntries]] a List of ExportEntry Records A List of ExportEntry records derived from the code of this module that correspond to export * declarations that occur within the module, not including export * as namespace declarations.

An ImportEntry Record is a Record that digests information about a single declarative import. Each ImportEntry Record has the fields defined in Table 56:

Table 56: ImportEntry Record Fields
Field Name Value Type Meaning
[[ModuleRequest]] a String String value of the ModuleSpecifier of the ImportDeclaration.
[[ImportName]] a String or namespace-object The name under which the desired binding is exported by the module identified by [[ModuleRequest]]. The value namespace-object indicates that the import request is for the target module's namespace object.
[[LocalName]] a String The name that is used to locally access the imported value from within the importing module.
Note 1

Table 57 gives examples of ImportEntry records fields used to represent the syntactic import forms:

Table 57 (Informative): Import Forms Mappings to ImportEntry Records
Import Statement Form [[ModuleRequest]] [[ImportName]] [[LocalName]]
import v from "mod"; "mod" "default" "v"
import * as ns from "mod"; "mod" namespace-object "ns"
import {x} from "mod"; "mod" "x" "x"
import {x as v} from "mod"; "mod" "x" "v"
import "mod"; An ImportEntry Record is not created.

An ExportEntry Record is a Record that digests information about a single declarative export. Each ExportEntry Record has the fields defined in Table 58:

Table 58: ExportEntry Record Fields
Field Name Value Type Meaning
[[ExportName]] a String or null The name used to export this binding by this module.
[[ModuleRequest]] a String or null The String value of the ModuleSpecifier of the ExportDeclaration. null if the ExportDeclaration does not have a ModuleSpecifier.
[[ImportName]] a String, null, all, or all-but-default The name under which the desired binding is exported by the module identified by [[ModuleRequest]]. null if the ExportDeclaration does not have a ModuleSpecifier. all is used for export * as ns from "mod" declarations. all-but-default is used for export * from "mod" declarations.
[[LocalName]] a String or null The name that is used to locally access the exported value from within the importing module. null if the exported value is not locally accessible from within the module.
Note 2

Table 59 gives examples of the ExportEntry record fields used to represent the syntactic export forms:

Table 59 (Informative): Export Forms Mappings to ExportEntry Records
Export Statement Form [[ExportName]] [[ModuleRequest]] [[ImportName]] [[LocalName]]
export var v; "v" null null "v"
export default function f() {} "default" null null "f"
export default function () {} "default" null null "*default*"
export default 42; "default" null null "*default*"
export {x}; "x" null null "x"
export {v as x}; "x" null null "v"
export {x} from "mod"; "x" "mod" "x" null
export {v as x} from "mod"; "x" "mod" "v" null
export * from "mod"; null "mod" all-but-default null
export * as ns from "mod"; "ns" "mod" all null

The following definitions specify the required concrete methods and other abstract operations for Source Text Module Records

16.2.1.6.1 ParseModule ( sourceText, realm, hostDefined )

The abstract operation ParseModule takes arguments sourceText (ECMAScript source text), realm (a Realm Record), and hostDefined (anything) and returns a Source Text Module Record or a non-empty List of SyntaxError objects. It creates a Source Text Module Record based upon the result of parsing sourceText as a Module. It performs the following steps when called:

  1. Let body be ParseText(sourceText, Module).
  2. If body is a List of errors, return body.
  3. Let requestedModules be the ModuleRequests of body.
  4. Let importEntries be ImportEntries of body.
  5. Let importedBoundNames be ImportedLocalNames(importEntries).
  6. Let indirectExportEntries be a new empty List.
  7. Let localExportEntries be a new empty List.
  8. Let starExportEntries be a new empty List.
  9. Let exportEntries be ExportEntries of body.
  10. For each ExportEntry Record ee of exportEntries, do
    1. If ee.[[ModuleRequest]] is null, then
      1. If importedBoundNames does not contain ee.[[LocalName]], then
        1. Append ee to localExportEntries.
      2. Else,
        1. Let ie be the element of importEntries whose [[LocalName]] is ee.[[LocalName]].
        2. If ie.[[ImportName]] is namespace-object, then
          1. NOTE: This is a re-export of an imported module namespace object.
          2. Append ee to localExportEntries.
        3. Else,
          1. NOTE: This is a re-export of a single name.
          2. Append the ExportEntry Record { [[ModuleRequest]]: ie.[[ModuleRequest]], [[ImportName]]: ie.[[ImportName]], [[LocalName]]: null, [[ExportName]]: ee.[[ExportName]] } to indirectExportEntries.
    2. Else if ee.[[ImportName]] is all-but-default, then
      1. Assert: ee.[[ExportName]] is null.
      2. Append ee to starExportEntries.
    3. Else,
      1. Append ee to indirectExportEntries.
  11. Let async be body Contains await.
  12. Return Source Text Module Record { [[Realm]]: realm, [[Environment]]: empty, [[Namespace]]: empty, [[CycleRoot]]: empty, [[HasTLA]]: async, [[AsyncEvaluation]]: false, [[TopLevelCapability]]: empty, [[AsyncParentModules]]: « », [[PendingAsyncDependencies]]: empty, [[Status]]: new, [[EvaluationError]]: empty, [[HostDefined]]: hostDefined, [[ECMAScriptCode]]: body, [[Context]]: empty, [[ImportMeta]]: empty, [[RequestedModules]]: requestedModules, [[LoadedModules]]: « », [[ImportEntries]]: importEntries, [[LocalExportEntries]]: localExportEntries, [[IndirectExportEntries]]: indirectExportEntries, [[StarExportEntries]]: starExportEntries, [[DFSIndex]]: empty, [[DFSAncestorIndex]]: empty }.
Note

An implementation may parse module source text and analyse it for Early Error conditions prior to the evaluation of ParseModule for that module source text. However, the reporting of any errors must be deferred until the point where this specification actually performs ParseModule upon that source text.

16.2.1.6.2 GetExportedNames ( [ exportStarSet ] )

The GetExportedNames concrete method of a Source Text Module Record module takes optional argument exportStarSet (a List of Source Text Module Records) and returns a List of Strings. It performs the following steps when called:

  1. Assert: module.[[Status]] is not new.
  2. If exportStarSet is not present, set exportStarSet to a new empty List.
  3. If exportStarSet contains module, then
    1. Assert: We've reached the starting point of an export * circularity.
    2. Return a new empty List.
  4. Append module to exportStarSet.
  5. Let exportedNames be a new empty List.
  6. For each ExportEntry Record e of module.[[LocalExportEntries]], do
    1. Assert: module provides the direct binding for this export.
    2. Assert: e.[[ExportName]] is not null.
    3. Append e.[[ExportName]] to exportedNames.
  7. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
    1. Assert: module imports a specific binding for this export.
    2. Assert: e.[[ExportName]] is not null.
    3. Append e.[[ExportName]] to exportedNames.
  8. For each ExportEntry Record e of module.[[StarExportEntries]], do
    1. Assert: e.[[ModuleRequest]] is not null.
    2. Let requestedModule be GetImportedModule(module, e.[[ModuleRequest]]).
    3. Let starNames be requestedModule.GetExportedNames(exportStarSet).
    4. For each element n of starNames, do
      1. If SameValue(n, "default") is false, then
        1. If exportedNames does not contain n, then
          1. Append n to exportedNames.
  9. Return exportedNames.
Note

GetExportedNames does not filter out or throw an exception for names that have ambiguous star export bindings.

16.2.1.6.3 ResolveExport ( exportName [ , resolveSet ] )

The ResolveExport concrete method of a Source Text Module Record module takes argument exportName (a String) and optional argument resolveSet (a List of Records with fields [[Module]] (a Module Record) and [[ExportName]] (a String)) and returns a ResolvedBinding Record, null, or ambiguous.

ResolveExport attempts to resolve an imported binding to the actual defining module and local binding name. The defining module may be the module represented by the Module Record this method was invoked on or some other module that is imported by that module. The parameter resolveSet is used to detect unresolved circular import/export paths. If a pair consisting of specific Module Record and exportName is reached that is already in resolveSet, an import circularity has been encountered. Before recursively calling ResolveExport, a pair consisting of module and exportName is added to resolveSet.

If a defining module is found, a ResolvedBinding Record { [[Module]], [[BindingName]] } is returned. This record identifies the resolved binding of the originally requested export, unless this is the export of a namespace with no local binding. In this case, [[BindingName]] will be set to namespace. If no definition was found or the request is found to be circular, null is returned. If the request is found to be ambiguous, ambiguous is returned.

It performs the following steps when called:

  1. Assert: module.[[Status]] is not new.
  2. If resolveSet is not present, set resolveSet to a new empty List.
  3. For each Record { [[Module]], [[ExportName]] } r of resolveSet, do
    1. If module and r.[[Module]] are the same Module Record and SameValue(exportName, r.[[ExportName]]) is true, then
      1. Assert: This is a circular import request.
      2. Return null.
  4. Append the Record { [[Module]]: module, [[ExportName]]: exportName } to resolveSet.
  5. For each ExportEntry Record e of module.[[LocalExportEntries]], do
    1. If SameValue(exportName, e.[[ExportName]]) is true, then
      1. Assert: module provides the direct binding for this export.
      2. Return ResolvedBinding Record { [[Module]]: module, [[BindingName]]: e.[[LocalName]] }.
  6. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
    1. If SameValue(exportName, e.[[ExportName]]) is true, then
      1. Assert: e.[[ModuleRequest]] is not null.
      2. Let importedModule be GetImportedModule(module, e.[[ModuleRequest]]).
      3. If e.[[ImportName]] is all, then
        1. Assert: module does not provide the direct binding for this export.
        2. Return ResolvedBinding Record { [[Module]]: importedModule, [[BindingName]]: namespace }.
      4. Else,
        1. Assert: module imports a specific binding for this export.
        2. Return importedModule.ResolveExport(e.[[ImportName]], resolveSet).
  7. If SameValue(exportName, "default") is true, then
    1. Assert: A default export was not explicitly defined by this module.
    2. Return null.
    3. NOTE: A default export cannot be provided by an export * from "mod" declaration.
  8. Let starResolution be null.
  9. For each ExportEntry Record e of module.[[StarExportEntries]], do
    1. Assert: e.[[ModuleRequest]] is not null.
    2. Let importedModule be GetImportedModule(module, e.[[ModuleRequest]]).
    3. Let resolution be importedModule.ResolveExport(exportName, resolveSet).
    4. If resolution is ambiguous, return ambiguous.
    5. If resolution is not null, then
      1. Assert: resolution is a ResolvedBinding Record.
      2. If starResolution is null, then
        1. Set starResolution to resolution.
      3. Else,
        1. Assert: There is more than one * import that includes the requested name.
        2. If resolution.[[Module]] and starResolution.[[Module]] are not the same Module Record, return ambiguous.
        3. If resolution.[[BindingName]] is not starResolution.[[BindingName]] and either resolution.[[BindingName]] or starResolution.[[BindingName]] is namespace, return ambiguous.
        4. If resolution.[[BindingName]] is a String, starResolution.[[BindingName]] is a String, and SameValue(resolution.[[BindingName]], starResolution.[[BindingName]]) is false, return ambiguous.
  10. Return starResolution.

16.2.1.6.4 InitializeEnvironment ( )

The InitializeEnvironment concrete method of a Source Text Module Record module takes no arguments and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
    1. Assert: e.[[ExportName]] is not null.
    2. Let resolution be module.ResolveExport(e.[[ExportName]]).
    3. If resolution is either null or ambiguous, throw a SyntaxError exception.
    4. Assert: resolution is a ResolvedBinding Record.
  2. Assert: All named exports from module are resolvable.
  3. Let realm be module.[[Realm]].
  4. Assert: realm is not undefined.
  5. Let env be NewModuleEnvironment(realm.[[GlobalEnv]]).
  6. Set module.[[Environment]] to env.
  7. For each ImportEntry Record in of module.[[ImportEntries]], do
    1. Let importedModule be GetImportedModule(module, in.[[ModuleRequest]]).
    2. If in.[[ImportName]] is namespace-object, then
      1. Let namespace be GetModuleNamespace(importedModule).
      2. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true).
      3. Perform ! env.InitializeBinding(in.[[LocalName]], namespace).
    3. Else,
      1. Let resolution be importedModule.ResolveExport(in.[[ImportName]]).
      2. If resolution is either null or ambiguous, throw a SyntaxError exception.
      3. If resolution.[[BindingName]] is namespace, then
        1. Let namespace be GetModuleNamespace(resolution.[[Module]]).
        2. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true).
        3. Perform ! env.InitializeBinding(in.[[LocalName]], namespace).
      4. Else,
        1. Perform env.CreateImportBinding(in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]).
  8. Let moduleContext be a new ECMAScript code execution context.
  9. Set the Function of moduleContext to null.
  10. Assert: module.[[Realm]] is not undefined.
  11. Set the Realm of moduleContext to module.[[Realm]].
  12. Set the ScriptOrModule of moduleContext to module.
  13. Set the VariableEnvironment of moduleContext to module.[[Environment]].
  14. Set the LexicalEnvironment of moduleContext to module.[[Environment]].
  15. Set the PrivateEnvironment of moduleContext to null.
  16. Set module.[[Context]] to moduleContext.
  17. Push moduleContext onto the execution context stack; moduleContext is now the running execution context.
  18. Let code be module.[[ECMAScriptCode]].
  19. Let varDeclarations be the VarScopedDeclarations of code.
  20. Let declaredVarNames be a new empty List.
  21. For each element d of varDeclarations, do
    1. For each element dn of the BoundNames of d, do
      1. If declaredVarNames does not contain dn, then
        1. Perform ! env.CreateMutableBinding(dn, false).
        2. Perform ! env.InitializeBinding(dn, undefined).
        3. Append dn to declaredVarNames.
  22. Let lexDeclarations be the LexicallyScopedDeclarations of code.
  23. Let privateEnv be null.
  24. For each element d of lexDeclarations, do
    1. For each element dn of the BoundNames of d, do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ! env.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ! env.CreateMutableBinding(dn, false).
      3. If d is either a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration, then
        1. Let fo be InstantiateFunctionObject of d with arguments env and privateEnv.
        2. Perform ! env.InitializeBinding(dn, fo).
  25. Remove moduleContext from the execution context stack.
  26. Return unused.

16.2.1.6.5 ExecuteModule ( [ capability ] )

The ExecuteModule concrete method of a Source Text Module Record module takes optional argument capability (a PromiseCapability Record) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let moduleContext be a new ECMAScript code execution context.
  2. Set the Function of moduleContext to null.
  3. Set the Realm of moduleContext to module.[[Realm]].
  4. Set the ScriptOrModule of moduleContext to module.
  5. Assert: module has been linked and declarations in its module environment have been instantiated.
  6. Set the VariableEnvironment of moduleContext to module.[[Environment]].
  7. Set the LexicalEnvironment of moduleContext to module.[[Environment]].
  8. Suspend the running execution context.
  9. If module.[[HasTLA]] is false, then
    1. Assert: capability is not present.
    2. Push moduleContext onto the execution context stack; moduleContext is now the running execution context.
    3. Let result be Completion(Evaluation of module.[[ECMAScriptCode]]).
    4. Suspend moduleContext and remove it from the execution context stack.
    5. Resume the context that is now on the top of the execution context stack as the running execution context.
    6. If result is an abrupt completion, then
      1. Return ? result.
  10. Else,
    1. Assert: capability is a PromiseCapability Record.
    2. Perform AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleContext).
  11. Return unused.

16.2.1.7 GetImportedModule ( referrer, specifier )

The abstract operation GetImportedModule takes arguments referrer (a Cyclic Module Record) and specifier (a String) and returns a Module Record. It performs the following steps when called:

  1. Assert: Exactly one element of referrer.[[LoadedModules]] is a Record whose [[Specifier]] is specifier, since LoadRequestedModules has completed successfully on referrer prior to invoking this abstract operation.
  2. Let record be the Record in referrer.[[LoadedModules]] whose [[Specifier]] is specifier.
  3. Return record.[[Module]].

16.2.1.8 HostLoadImportedModule ( referrer, specifier, hostDefined, payload )

The host-defined abstract operation HostLoadImportedModule takes arguments referrer (a Script Record, a Cyclic Module Record, or a Realm Record), specifier (a String), hostDefined (anything), and payload (a GraphLoadingState Record or a PromiseCapability Record) and returns unused.

Note

An example of when referrer can be a Realm Record is in a web browser host. There, if a user clicks on a control given by

<button type="button" onclick="import('./foo.mjs')">Click me</button>

there will be no active script or module at the time the import() expression runs. More generally, this can happen in any situation where the host pushes execution contexts with null ScriptOrModule components onto the execution context stack.

An implementation of HostLoadImportedModule must conform to the following requirements:

The actual process performed is host-defined, but typically consists of performing whatever I/O operations are necessary to load the appropriate Module Record. Multiple different (referrer, specifier) pairs may map to the same Module Record instance. The actual mapping semantics is host-defined but typically a normalization process is applied to specifier as part of the mapping process. A typical normalization process would include actions such as expansion of relative and abbreviated path specifiers.

16.2.1.9 FinishLoadingImportedModule ( referrer, specifier, payload, result )

The abstract operation FinishLoadingImportedModule takes arguments referrer (a Script Record, a Cyclic Module Record, or a Realm Record), specifier (a String), payload (a GraphLoadingState Record or a PromiseCapability Record), and result (either a normal completion containing a Module Record or a throw completion) and returns unused. It performs the following steps when called:

  1. If result is a normal completion, then
    1. If referrer.[[LoadedModules]] contains a Record whose [[Specifier]] is specifier, then
      1. Assert: That Record's [[Module]] is result.[[Value]].
    2. Else,
      1. Append the Record { [[Specifier]]: specifier, [[Module]]: result.[[Value]] } to referrer.[[LoadedModules]].
  2. If payload is a GraphLoadingState Record, then
    1. Perform ContinueModuleLoading(payload, result).
  3. Else,
    1. Perform ContinueDynamicImport(payload, result).
  4. Return unused.

16.2.1.10 GetModuleNamespace ( module )

The abstract operation GetModuleNamespace takes argument module (an instance of a concrete subclass of Module Record) and returns a Module Namespace Object or empty. It retrieves the Module Namespace Object representing module's exports, lazily creating it the first time it was requested, and storing it in module.[[Namespace]] for future retrieval. It performs the following steps when called:

  1. Assert: If module is a Cyclic Module Record, then module.[[Status]] is not new or unlinked.
  2. Let namespace be module.[[Namespace]].
  3. If namespace is empty, then
    1. Let exportedNames be module.GetExportedNames().
    2. Let unambiguousNames be a new empty List.
    3. For each element name of exportedNames, do
      1. Let resolution be module.ResolveExport(name).
      2. If resolution is a ResolvedBinding Record, append name to unambiguousNames.
    4. Set namespace to ModuleNamespaceCreate(module, unambiguousNames).
  4. Return namespace.
Note

GetModuleNamespace never throws. Instead, unresolvable names are simply excluded from the namespace at this point. They will lead to a real linking error later unless they are all ambiguous star exports that are not explicitly requested anywhere.

16.2.1.11 Runtime Semantics: Evaluation

Module : [empty]
  1. Return undefined.
ModuleBody : ModuleItemList
  1. Let result be Completion(Evaluation of ModuleItemList).
  2. If result is a normal completion and result.[[Value]] is empty, then
    1. Return undefined.
  3. Return ? result.
ModuleItemList : ModuleItemList ModuleItem
  1. Let sl be ? Evaluation of ModuleItemList.
  2. Let s be Completion(Evaluation of ModuleItem).
  3. Return ? UpdateEmpty(s, sl).
Note

The value of a ModuleItemList is the value of the last value-producing item in the ModuleItemList.

ModuleItem : ImportDeclaration
  1. Return empty.

16.2.2 Imports

Syntax

ImportDeclaration : import ImportClause FromClause ; import ModuleSpecifier ; ImportClause : ImportedDefaultBinding NameSpaceImport NamedImports ImportedDefaultBinding , NameSpaceImport ImportedDefaultBinding , NamedImports ImportedDefaultBinding : ImportedBinding NameSpaceImport : * as ImportedBinding NamedImports : { } { ImportsList } { ImportsList , } FromClause : from ModuleSpecifier ImportsList : ImportSpecifier ImportsList , ImportSpecifier ImportSpecifier : ImportedBinding ModuleExportName as ImportedBinding ModuleSpecifier : StringLiteral ImportedBinding : BindingIdentifier[~Yield, +Await]

16.2.2.1 Static Semantics: Early Errors

ModuleItem : ImportDeclaration

16.2.2.2 Static Semantics: ImportEntries

The syntax-directed operation ImportEntries takes no arguments and returns a List of ImportEntry Records. It is defined piecewise over the following productions:

Module : [empty]
  1. Return a new empty List.
ModuleItemList : ModuleItemList ModuleItem
  1. Let entries1 be ImportEntries of ModuleItemList.
  2. Let entries2 be ImportEntries of ModuleItem.
  3. Return the list-concatenation of entries1 and entries2.
ModuleItem : ExportDeclaration StatementListItem
  1. Return a new empty List.
ImportDeclaration : import ImportClause FromClause ;
  1. Let module be the sole element of ModuleRequests of FromClause.
  2. Return ImportEntriesForModule of ImportClause with argument module.
ImportDeclaration : import ModuleSpecifier ;
  1. Return a new empty List.

16.2.2.3 Static Semantics: ImportEntriesForModule

The syntax-directed operation ImportEntriesForModule takes argument module (a String) and returns a List of ImportEntry Records. It is defined piecewise over the following productions:

ImportClause : ImportedDefaultBinding , NameSpaceImport
  1. Let entries1 be ImportEntriesForModule of ImportedDefaultBinding with argument module.
  2. Let entries2 be ImportEntriesForModule of NameSpaceImport with argument module.
  3. Return the list-concatenation of entries1 and entries2.
ImportClause : ImportedDefaultBinding , NamedImports
  1. Let entries1 be ImportEntriesForModule of ImportedDefaultBinding with argument module.
  2. Let entries2 be ImportEntriesForModule of NamedImports with argument module.
  3. Return the list-concatenation of entries1 and entries2.
ImportedDefaultBinding : ImportedBinding
  1. Let localName be the sole element of BoundNames of ImportedBinding.
  2. Let defaultEntry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: "default", [[LocalName]]: localName }.
  3. Return « defaultEntry ».
NameSpaceImport : * as ImportedBinding
  1. Let localName be the StringValue of ImportedBinding.
  2. Let entry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: namespace-object, [[LocalName]]: localName }.
  3. Return « entry ».
NamedImports : { }
  1. Return a new empty List.
ImportsList : ImportsList , ImportSpecifier
  1. Let specs1 be the ImportEntriesForModule of ImportsList with argument module.
  2. Let specs2 be the ImportEntriesForModule of ImportSpecifier with argument module.
  3. Return the list-concatenation of specs1 and specs2.
ImportSpecifier : ImportedBinding
  1. Let localName be the sole element of BoundNames of ImportedBinding.
  2. Let entry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: localName, [[LocalName]]: localName }.
  3. Return « entry ».
ImportSpecifier : ModuleExportName as ImportedBinding
  1. Let importName be the StringValue of ModuleExportName.
  2. Let localName be the StringValue of ImportedBinding.
  3. Let entry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName }.
  4. Return « entry ».

16.2.3 Exports

Syntax

ExportDeclaration : export ExportFromClause FromClause ; export NamedExports ; export VariableStatement[~Yield, +Await] export Declaration[~Yield, +Await] export default HoistableDeclaration[~Yield, +Await, +Default] export default ClassDeclaration[~Yield, +Await, +Default] export default [lookahead ∉ { function, async [no LineTerminator here] function, class }] AssignmentExpression[+In, ~Yield, +Await] ; ExportFromClause : * * as ModuleExportName NamedExports NamedExports : { } { ExportsList } { ExportsList , } ExportsList : ExportSpecifier ExportsList , ExportSpecifier ExportSpecifier : ModuleExportName ModuleExportName as ModuleExportName

16.2.3.1 Static Semantics: Early Errors

ExportDeclaration : export NamedExports ; Note

The above rule means that each ReferencedBindings of NamedExports is treated as an IdentifierReference.

16.2.3.2 Static Semantics: ExportedBindings

The syntax-directed operation ExportedBindings takes no arguments and returns a List of Strings.

Note

ExportedBindings are the locally bound names that are explicitly associated with a Module's ExportedNames.

It is defined piecewise over the following productions:

ModuleItemList : ModuleItemList ModuleItem
  1. Let names1 be ExportedBindings of ModuleItemList.
  2. Let names2 be ExportedBindings of ModuleItem.
  3. Return the list-concatenation of names1 and names2.
ModuleItem : ImportDeclaration StatementListItem
  1. Return a new empty List.
ExportDeclaration : export ExportFromClause FromClause ;
  1. Return a new empty List.
ExportDeclaration : export NamedExports ;
  1. Return the ExportedBindings of NamedExports.
ExportDeclaration : export VariableStatement
  1. Return the BoundNames of VariableStatement.
ExportDeclaration : export Declaration
  1. Return the BoundNames of Declaration.
ExportDeclaration : export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. Return the BoundNames of this ExportDeclaration.
NamedExports : { }
  1. Return a new empty List.
ExportsList : ExportsList , ExportSpecifier
  1. Let names1 be the ExportedBindings of ExportsList.
  2. Let names2 be the ExportedBindings of ExportSpecifier.
  3. Return the list-concatenation of names1 and names2.
ExportSpecifier : ModuleExportName
  1. Return a List whose sole element is the StringValue of ModuleExportName.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. Return a List whose sole element is the StringValue of the first ModuleExportName.

16.2.3.3 Static Semantics: ExportedNames

The syntax-directed operation ExportedNames takes no arguments and returns a List of Strings.

Note

ExportedNames are the externally visible names that a Module explicitly maps to one of its local name bindings.

It is defined piecewise over the following productions:

ModuleItemList : ModuleItemList ModuleItem
  1. Let names1 be ExportedNames of ModuleItemList.
  2. Let names2 be ExportedNames of ModuleItem.
  3. Return the list-concatenation of names1 and names2.
ModuleItem : ExportDeclaration
  1. Return the ExportedNames of ExportDeclaration.
ModuleItem : ImportDeclaration StatementListItem
  1. Return a new empty List.
ExportDeclaration : export ExportFromClause FromClause ;
  1. Return the ExportedNames of ExportFromClause.
ExportFromClause : *
  1. Return a new empty List.
ExportFromClause : * as ModuleExportName
  1. Return a List whose sole element is the StringValue of ModuleExportName.
ExportFromClause : NamedExports
  1. Return the ExportedNames of NamedExports.
ExportDeclaration : export VariableStatement
  1. Return the BoundNames of VariableStatement.
ExportDeclaration : export Declaration
  1. Return the BoundNames of Declaration.
ExportDeclaration : export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. Return « "default" ».
NamedExports : { }
  1. Return a new empty List.
ExportsList : ExportsList , ExportSpecifier
  1. Let names1 be the ExportedNames of ExportsList.
  2. Let names2 be the ExportedNames of ExportSpecifier.
  3. Return the list-concatenation of names1 and names2.
ExportSpecifier : ModuleExportName
  1. Return a List whose sole element is the StringValue of ModuleExportName.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. Return a List whose sole element is the StringValue of the second ModuleExportName.

16.2.3.4 Static Semantics: ExportEntries

The syntax-directed operation ExportEntries takes no arguments and returns a List of ExportEntry Records. It is defined piecewise over the following productions:

Module : [empty]
  1. Return a new empty List.
ModuleItemList : ModuleItemList ModuleItem
  1. Let entries1 be ExportEntries of ModuleItemList.
  2. Let entries2 be ExportEntries of ModuleItem.
  3. Return the list-concatenation of entries1 and entries2.
ModuleItem : ImportDeclaration StatementListItem
  1. Return a new empty List.
ExportDeclaration : export ExportFromClause FromClause ;
  1. Let module be the sole element of ModuleRequests of FromClause.
  2. Return ExportEntriesForModule of ExportFromClause with argument module.
ExportDeclaration : export NamedExports ;
  1. Return ExportEntriesForModule of NamedExports with argument null.
ExportDeclaration : export VariableStatement
  1. Let entries be a new empty List.
  2. Let names be the BoundNames of VariableStatement.
  3. For each element name of names, do
    1. Append the ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } to entries.
  4. Return entries.
ExportDeclaration : export Declaration
  1. Let entries be a new empty List.
  2. Let names be the BoundNames of Declaration.
  3. For each element name of names, do
    1. Append the ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } to entries.
  4. Return entries.
ExportDeclaration : export default HoistableDeclaration
  1. Let names be BoundNames of HoistableDeclaration.
  2. Let localName be the sole element of names.
  3. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" }.
ExportDeclaration : export default ClassDeclaration
  1. Let names be BoundNames of ClassDeclaration.
  2. Let localName be the sole element of names.
  3. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" }.
ExportDeclaration : export default AssignmentExpression ;
  1. Let entry be the ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: "*default*", [[ExportName]]: "default" }.
  2. Return « entry ».
Note

"*default*" is used within this specification as a synthetic name for anonymous default export values. See this note for more details.

16.2.3.5 Static Semantics: ExportEntriesForModule

The syntax-directed operation ExportEntriesForModule takes argument module (a String or null) and returns a List of ExportEntry Records. It is defined piecewise over the following productions:

ExportFromClause : *
  1. Let entry be the ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: all-but-default, [[LocalName]]: null, [[ExportName]]: null }.
  2. Return « entry ».
ExportFromClause : * as ModuleExportName
  1. Let exportName be the StringValue of ModuleExportName.
  2. Let entry be the ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: all, [[LocalName]]: null, [[ExportName]]: exportName }.
  3. Return « entry ».
NamedExports : { }
  1. Return a new empty List.
ExportsList : ExportsList , ExportSpecifier
  1. Let specs1 be the ExportEntriesForModule of ExportsList with argument module.
  2. Let specs2 be the ExportEntriesForModule of ExportSpecifier with argument module.
  3. Return the list-concatenation of specs1 and specs2.
ExportSpecifier : ModuleExportName
  1. Let sourceName be the StringValue of ModuleExportName.
  2. If module is null, then
    1. Let localName be sourceName.
    2. Let importName be null.
  3. Else,
    1. Let localName be null.
    2. Let importName be sourceName.
  4. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: sourceName }.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. Let sourceName be the StringValue of the first ModuleExportName.
  2. Let exportName be the StringValue of the second ModuleExportName.
  3. If module is null, then
    1. Let localName be sourceName.
    2. Let importName be null.
  4. Else,
    1. Let localName be null.
    2. Let importName be sourceName.
  5. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: exportName }.

16.2.3.6 Static Semantics: ReferencedBindings

The syntax-directed operation ReferencedBindings takes no arguments and returns a List of Parse Nodes. It is defined piecewise over the following productions:

NamedExports : { }
  1. Return a new empty List.
ExportsList : ExportsList , ExportSpecifier
  1. Let names1 be the ReferencedBindings of ExportsList.
  2. Let names2 be the ReferencedBindings of ExportSpecifier.
  3. Return the list-concatenation of names1 and names2.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. Return the ReferencedBindings of the first ModuleExportName.
ModuleExportName : IdentifierName
  1. Return a List whose sole element is the IdentifierName.
ModuleExportName : StringLiteral
  1. Return a List whose sole element is the StringLiteral.

16.2.3.7 Runtime Semantics: Evaluation

ExportDeclaration : export ExportFromClause FromClause ; export NamedExports ;
  1. Return empty.
ExportDeclaration : export VariableStatement
  1. Return ? Evaluation of VariableStatement.
ExportDeclaration : export Declaration
  1. Return ? Evaluation of Declaration.
ExportDeclaration : export default HoistableDeclaration
  1. Return ? Evaluation of HoistableDeclaration.
ExportDeclaration : export default ClassDeclaration
  1. Let value be ? BindingClassDeclarationEvaluation of ClassDeclaration.
  2. Let className be the sole element of BoundNames of ClassDeclaration.
  3. If className is "*default*", then
    1. Let env be the running execution context's LexicalEnvironment.
    2. Perform ? InitializeBoundName("*default*", value, env).
  4. Return empty.
ExportDeclaration : export default AssignmentExpression ;
  1. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let value be ? NamedEvaluation of AssignmentExpression with argument "default".
  2. Else,
    1. Let rhs be ? Evaluation of AssignmentExpression.
    2. Let value be ? GetValue(rhs).
  3. Let env be the running execution context's LexicalEnvironment.
  4. Perform ? InitializeBoundName("*default*", value, env).
  5. Return empty.

17 Error Handling and Language Extensions

An implementation must report most errors at the time the relevant ECMAScript language construct is evaluated. An early error is an error that can be detected and reported prior to the evaluation of any construct in the Script containing the error. The presence of an early error prevents the evaluation of the construct. An implementation must report early errors in a Script as part of parsing that Script in ParseScript. Early errors in a Module are reported at the point when the Module would be evaluated and the Module is never initialized. Early errors in eval code are reported at the time eval is called and prevent evaluation of the eval code. All errors that are not early errors are runtime errors.

An implementation must report as an early error any occurrence of a condition that is listed in a “Static Semantics: Early Errors” subclause of this specification.

An implementation shall not treat other kinds of errors as early errors even if the compiler can prove that a construct cannot execute without error under any circumstances. An implementation may issue an early warning in such a case, but it should not report the error until the relevant construct is actually executed.

An implementation shall report all errors as specified, except for the following:

17.1 Forbidden Extensions

An implementation must not extend this specification in the following ways:

18 ECMAScript Standard Built-in Objects

There are certain built-in objects available whenever an ECMAScript Script or Module begins execution. One, the global object, is part of the global environment of the executing program. Others are accessible as initial properties of the global object or indirectly as properties of accessible built-in objects.

Unless specified otherwise, a built-in object that is callable as a function is a built-in function object with the characteristics described in 10.3. Unless specified otherwise, the [[Extensible]] internal slot of a built-in object initially has the value true. Every built-in function object has a [[Realm]] internal slot whose value is the Realm Record of the realm for which the object was initially created.

Many built-in objects are functions: they can be invoked with arguments. Some of them furthermore are constructors: they are functions intended for use with the new operator. For each built-in function, this specification describes the arguments required by that function and the properties of that function object. For each built-in constructor, this specification furthermore describes properties of the prototype object of that constructor and properties of specific object instances returned by a new expression that invokes that constructor.

Unless otherwise specified in the description of a particular function, if a built-in function or constructor is given fewer arguments than the function is specified to require, the function or constructor shall behave exactly as if it had been given sufficient additional arguments, each such argument being the undefined value. Such missing arguments are considered to be “not present” and may be identified in that manner by specification algorithms. In the description of a particular function, the terms “this value” and “NewTarget” have the meanings given in 10.3.

Unless otherwise specified in the description of a particular function, if a built-in function or constructor described is given more arguments than the function is specified to allow, the extra arguments are evaluated by the call and then ignored by the function. However, an implementation may define implementation specific behaviour relating to such arguments as long as the behaviour is not the throwing of a TypeError exception that is predicated simply on the presence of an extra argument.

Note 1

Implementations that add additional capabilities to the set of built-in functions are encouraged to do so by adding new functions rather than adding new parameters to existing functions.

Unless otherwise specified every built-in function and every built-in constructor has the Function prototype object, which is the initial value of the expression Function.prototype (20.2.3), as the value of its [[Prototype]] internal slot.

Unless otherwise specified every built-in prototype object has the Object prototype object, which is the initial value of the expression Object.prototype (20.1.3), as the value of its [[Prototype]] internal slot, except the Object prototype object itself.

If this specification defines a built-in constructor's behaviour via algorithm steps, then that is its behaviour for the purposes of both [[Call]] and [[Construct]]. If such an algorithm needs to distinguish the two cases, it checks whether NewTarget is undefined, which indicates a [[Call]] invocation.

Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function.

Built-in function objects that are not constructors do not have a "prototype" property unless otherwise specified in the description of a particular function.

Each built-in function defined in this specification is created by calling the CreateBuiltinFunction abstract operation (10.3.4). The values of the length and name parameters are the initial values of the "length" and "name" properties as discussed below. The values of the prefix parameter are similarly discussed below.

Every built-in function object, including constructors, has a "length" property whose value is a non-negative integral Number. Unless otherwise specified, this value is the number of required parameters shown in the subclause heading for the function description. Optional parameters and rest parameters are not included in the parameter count.

Note 2

For example, the function object that is the initial value of the "map" property of the Array prototype object is described under the subclause heading «Array.prototype.map (callbackFn [ , thisArg])» which shows the two named arguments callbackFn and thisArg, the latter being optional; therefore the value of the "length" property of that function object is 1𝔽.

Unless otherwise specified, the "length" property of a built-in function object has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Every built-in function object, including constructors, has a "name" property whose value is a String. Unless otherwise specified, this value is the name that is given to the function in this specification. Functions that are identified as anonymous functions use the empty String as the value of the "name" property. For functions that are specified as properties of objects, the name value is the property name string used to access the function. Functions that are specified as get or set accessor functions of built-in properties have "get" or "set" (respectively) passed to the prefix parameter when calling CreateBuiltinFunction.

The value of the "name" property is explicitly specified for each built-in functions whose property key is a Symbol value. If such an explicitly specified value starts with the prefix "get " or "set " and the function for which it is specified is a get or set accessor function of a built-in property, the value without the prefix is passed to the name parameter, and the value "get" or "set" (respectively) is passed to the prefix parameter when calling CreateBuiltinFunction.

Unless otherwise specified, the "name" property of a built-in function object has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified.

Every accessor property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. If only a get accessor function is described, the set accessor function is the default value, undefined. If only a set accessor is described the get accessor is the default value, undefined.

19 The Global Object

The global object:

19.1 Value Properties of the Global Object

19.1.1 globalThis

The initial value of the "globalThis" property of the global object in a Realm Record realm is realm.[[GlobalEnv]].[[GlobalThisValue]].

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.

19.1.2 Infinity

The value of Infinity is +∞𝔽 (see 6.1.6.1). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.1.3 NaN

The value of NaN is NaN (see 6.1.6.1). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.1.4 undefined

The value of undefined is undefined (see 6.1.1). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.2 Function Properties of the Global Object

19.2.1 eval ( x )

This function is the %eval% intrinsic object.

It performs the following steps when called:

  1. Return ? PerformEval(x, false, false).

19.2.1.1 PerformEval ( x, strictCaller, direct )

The abstract operation PerformEval takes arguments x (an ECMAScript language value), strictCaller (a Boolean), and direct (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Assert: If direct is false, then strictCaller is also false.
  2. If x is not a String, return x.
  3. Let evalRealm be the current Realm Record.
  4. NOTE: In the case of a direct eval, evalRealm is the realm of both the caller of eval and of the eval function itself.
  5. Perform ? HostEnsureCanCompileStrings(evalRealm, « », x, direct).
  6. Let inFunction be false.
  7. Let inMethod be false.
  8. Let inDerivedConstructor be false.
  9. Let inClassFieldInitializer be false.
  10. If direct is true, then
    1. Let thisEnvRec be GetThisEnvironment().
    2. If thisEnvRec is a Function Environment Record, then
      1. Let F be thisEnvRec.[[FunctionObject]].
      2. Set inFunction to true.
      3. Set inMethod to thisEnvRec.HasSuperBinding().
      4. If F.[[ConstructorKind]] is derived, set inDerivedConstructor to true.
      5. Let classFieldInitializerName be F.[[ClassFieldInitializerName]].
      6. If classFieldInitializerName is not empty, set inClassFieldInitializer to true.
  11. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection:
    1. Let script be ParseText(StringToCodePoints(x), Script).
    2. If script is a List of errors, throw a SyntaxError exception.
    3. If script Contains ScriptBody is false, return undefined.
    4. Let body be the ScriptBody of script.
    5. If inFunction is false and body Contains NewTarget, throw a SyntaxError exception.
    6. If inMethod is false and body Contains SuperProperty, throw a SyntaxError exception.
    7. If inDerivedConstructor is false and body Contains SuperCall, throw a SyntaxError exception.
    8. If inClassFieldInitializer is true and ContainsArguments of body is true, throw a SyntaxError exception.
  12. If strictCaller is true, let strictEval be true.
  13. Else, let strictEval be IsStrict of script.
  14. Let runningContext be the running execution context.
  15. NOTE: If direct is true, runningContext will be the execution context that performed the direct eval. If direct is false, runningContext will be the execution context for the invocation of the eval function.
  16. If direct is true, then
    1. Let lexEnv be NewDeclarativeEnvironment(runningContext's LexicalEnvironment).
    2. Let varEnv be runningContext's VariableEnvironment.
    3. Let privateEnv be runningContext's PrivateEnvironment.
  17. Else,
    1. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
    2. Let varEnv be evalRealm.[[GlobalEnv]].
    3. Let privateEnv be null.
  18. If strictEval is true, set varEnv to lexEnv.
  19. If runningContext is not already suspended, suspend runningContext.
  20. Let evalContext be a new ECMAScript code execution context.
  21. Set evalContext's Function to null.
  22. Set evalContext's Realm to evalRealm.
  23. Set evalContext's ScriptOrModule to runningContext's ScriptOrModule.
  24. Set evalContext's VariableEnvironment to varEnv.
  25. Set evalContext's LexicalEnvironment to lexEnv.
  26. Set evalContext's PrivateEnvironment to privateEnv.
  27. Push evalContext onto the execution context stack; evalContext is now the running execution context.
  28. Let result be Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, privateEnv, strictEval)).
  29. If result is a normal completion, then
    1. Set result to Completion(Evaluation of body).
  30. If result is a normal completion and result.[[Value]] is empty, then
    1. Set result to NormalCompletion(undefined).
  31. Suspend evalContext and remove it from the execution context stack.
  32. Resume the context that is now on the top of the execution context stack as the running execution context.
  33. Return ? result.
Note

The eval code cannot instantiate variable or function bindings in the variable environment of the calling context that invoked the eval if either the code of the calling context or the eval code is strict mode code. Instead such bindings are instantiated in a new VariableEnvironment that is only accessible to the eval code. Bindings introduced by let, const, or class declarations are always instantiated in a new LexicalEnvironment.

19.2.1.2 HostEnsureCanCompileStrings ( calleeRealm, parameterStrings, bodyString, direct )

The host-defined abstract operation HostEnsureCanCompileStrings takes arguments calleeRealm (a Realm Record), parameterStrings (a List of Strings), bodyString (a String), and direct (a Boolean) and returns either a normal completion containing unused or a throw completion. It allows host environments to block certain ECMAScript functions which allow developers to interpret and evaluate strings as ECMAScript code.

parameterStrings represents the strings that, when using one of the function constructors, will be concatenated together to build the parameters list. bodyString represents the function body or the string passed to an eval call. direct signifies whether the evaluation is a direct eval.

The default implementation of HostEnsureCanCompileStrings is to return NormalCompletion(unused).

19.2.1.3 EvalDeclarationInstantiation ( body, varEnv, lexEnv, privateEnv, strict )

The abstract operation EvalDeclarationInstantiation takes arguments body (a ScriptBody Parse Node), varEnv (an Environment Record), lexEnv (a Declarative Environment Record), privateEnv (a PrivateEnvironment Record or null), and strict (a Boolean) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let varNames be the VarDeclaredNames of body.
  2. Let varDeclarations be the VarScopedDeclarations of body.
  3. If strict is false, then
    1. If varEnv is a Global Environment Record, then
      1. For each element name of varNames, do
        1. If varEnv.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
        2. NOTE: eval will not create a global var declaration that would be shadowed by a global lexical declaration.
    2. Let thisEnv be lexEnv.
    3. Assert: The following loop will terminate.
    4. Repeat, while thisEnv is not varEnv,
      1. If thisEnv is not an Object Environment Record, then
        1. NOTE: The environment of with statements cannot contain any lexical declaration so it doesn't need to be checked for var/let hoisting conflicts.
        2. For each element name of varNames, do
          1. If ! thisEnv.HasBinding(name) is true, then
            1. Throw a SyntaxError exception.
            2. NOTE: Annex B.3.4 defines alternate semantics for the above step.
          2. NOTE: A direct eval will not hoist var declaration over a like-named lexical declaration.
      2. Set thisEnv to thisEnv.[[OuterEnv]].
  4. Let privateIdentifiers be a new empty List.
  5. Let pointer be privateEnv.
  6. Repeat, while pointer is not null,
    1. For each Private Name binding of pointer.[[Names]], do
      1. If privateIdentifiers does not contain binding.[[Description]], append binding.[[Description]] to privateIdentifiers.
    2. Set pointer to pointer.[[OuterPrivateEnvironment]].
  7. If AllPrivateIdentifiersValid of body with argument privateIdentifiers is false, throw a SyntaxError exception.
  8. Let functionsToInitialize be a new empty List.
  9. Let declaredFunctionNames be a new empty List.
  10. For each element d of varDeclarations, in reverse List order, do
    1. If d is not either a VariableDeclaration, a ForBinding, or a BindingIdentifier, then
      1. Assert: d is either a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration.
      2. NOTE: If there are multiple function declarations for the same name, the last declaration is used.
      3. Let fn be the sole element of the BoundNames of d.
      4. If declaredFunctionNames does not contain fn, then
        1. If varEnv is a Global Environment Record, then
          1. Let fnDefinable be ? varEnv.CanDeclareGlobalFunction(fn).
          2. If fnDefinable is false, throw a TypeError exception.
        2. Append fn to declaredFunctionNames.
        3. Insert d as the first element of functionsToInitialize.
  11. Let declaredVarNames be a new empty List.
  12. For each element d of varDeclarations, do
    1. If d is either a VariableDeclaration, a ForBinding, or a BindingIdentifier, then
      1. For each String vn of the BoundNames of d, do
        1. If declaredFunctionNames does not contain vn, then
          1. If varEnv is a Global Environment Record, then
            1. Let vnDefinable be ? varEnv.CanDeclareGlobalVar(vn).
            2. If vnDefinable is false, throw a TypeError exception.
          2. If declaredVarNames does not contain vn, then
            1. Append vn to declaredVarNames.
  13. NOTE: Annex B.3.2.3 adds additional steps at this point.
  14. NOTE: No abnormal terminations occur after this algorithm step unless varEnv is a Global Environment Record and the global object is a Proxy exotic object.
  15. Let lexDeclarations be the LexicallyScopedDeclarations of body.
  16. For each element d of lexDeclarations, do
    1. NOTE: Lexically declared names are only instantiated here but not initialized.
    2. For each element dn of the BoundNames of d, do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ? lexEnv.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ? lexEnv.CreateMutableBinding(dn, false).
  17. For each Parse Node f of functionsToInitialize, do
    1. Let fn be the sole element of the BoundNames of f.
    2. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
    3. If varEnv is a Global Environment Record, then
      1. Perform ? varEnv.CreateGlobalFunctionBinding(fn, fo, true).
    4. Else,
      1. Let bindingExists be ! varEnv.HasBinding(fn).
      2. If bindingExists is false, then
        1. NOTE: The following invocation cannot return an abrupt completion because of the validation preceding step 14.
        2. Perform ! varEnv.CreateMutableBinding(fn, true).
        3. Perform ! varEnv.InitializeBinding(fn, fo).
      3. Else,
        1. Perform ! varEnv.SetMutableBinding(fn, fo, false).
  18. For each String vn of declaredVarNames, do
    1. If varEnv is a Global Environment Record, then
      1. Perform ? varEnv.CreateGlobalVarBinding(vn, true).
    2. Else,
      1. Let bindingExists be ! varEnv.HasBinding(vn).
      2. If bindingExists is false, then
        1. NOTE: The following invocation cannot return an abrupt completion because of the validation preceding step 14.
        2. Perform ! varEnv.CreateMutableBinding(vn, true).
        3. Perform ! varEnv.InitializeBinding(vn, undefined).
  19. Return unused.
Note

An alternative version of this algorithm is described in B.3.4.

19.2.2 isFinite ( number )

This function is the %isFinite% intrinsic object.

It performs the following steps when called:

  1. Let num be ? ToNumber(number).
  2. If num is not finite, return false.
  3. Otherwise, return true.

19.2.3 isNaN ( number )

This function is the %isNaN% intrinsic object.

It performs the following steps when called:

  1. Let num be ? ToNumber(number).
  2. If num is NaN, return true.
  3. Otherwise, return false.
Note

A reliable way for ECMAScript code to test if a value X is NaN is an expression of the form X !== X. The result will be true if and only if X is NaN.

19.2.4 parseFloat ( string )

This function produces a Number value dictated by interpretation of the contents of the string argument as a decimal literal.

It is the %parseFloat% intrinsic object.

It performs the following steps when called:

  1. Let inputString be ? ToString(string).
  2. Let trimmedString be ! TrimString(inputString, start).
  3. Let trimmed be StringToCodePoints(trimmedString).
  4. Let trimmedPrefix be the longest prefix of trimmed that satisfies the syntax of a StrDecimalLiteral, which might be trimmed itself. If there is no such prefix, return NaN.
  5. Let parsedNumber be ParseText(trimmedPrefix, StrDecimalLiteral).
  6. Assert: parsedNumber is a Parse Node.
  7. Return StringNumericValue of parsedNumber.
Note

This function may interpret only a leading portion of string as a Number value; it ignores any code units that cannot be interpreted as part of the notation of a decimal literal, and no indication is given that any such code units were ignored.

19.2.5 parseInt ( string, radix )

This function produces an integral Number dictated by interpretation of the contents of string according to the specified radix. Leading white space in string is ignored. If radix coerces to 0 (such as when it is undefined), it is assumed to be 10 except when the number representation begins with "0x" or "0X", in which case it is assumed to be 16. If radix is 16, the number representation may optionally begin with "0x" or "0X".

It is the %parseInt% intrinsic object.

It performs the following steps when called:

  1. Let inputString be ? ToString(string).
  2. Let S be ! TrimString(inputString, start).
  3. Let sign be 1.
  4. If S is not empty and the first code unit of S is the code unit 0x002D (HYPHEN-MINUS), set sign to -1.
  5. If S is not empty and the first code unit of S is either the code unit 0x002B (PLUS SIGN) or the code unit 0x002D (HYPHEN-MINUS), set S to the substring of S from index 1.
  6. Let R be (? ToInt32(radix)).
  7. Let stripPrefix be true.
  8. If R ≠ 0, then
    1. If R < 2 or R > 36, return NaN.
    2. If R ≠ 16, set stripPrefix to false.
  9. Else,
    1. Set R to 10.
  10. If stripPrefix is true, then
    1. If the length of S is at least 2 and the first two code units of S are either "0x" or "0X", then
      1. Set S to the substring of S from index 2.
      2. Set R to 16.
  11. If S contains a code unit that is not a radix-R digit, let end be the index within S of the first such code unit; otherwise, let end be the length of S.
  12. Let Z be the substring of S from 0 to end.
  13. If Z is empty, return NaN.
  14. Let mathInt be the integer value that is represented by Z in radix-R notation, using the letters A through Z and a through z for digits with values 10 through 35. (However, if R = 10 and Z contains more than 20 significant digits, every significant digit after the 20th may be replaced by a 0 digit, at the option of the implementation; and if R is not one of 2, 4, 8, 10, 16, or 32, then mathInt may be an implementation-approximated integer representing the integer value denoted by Z in radix-R notation.)
  15. If mathInt = 0, then
    1. If sign = -1, return -0𝔽.
    2. Return +0𝔽.
  16. Return 𝔽(sign × mathInt).
Note

This function may interpret only a leading portion of string as an integer value; it ignores any code units that cannot be interpreted as part of the notation of an integer, and no indication is given that any such code units were ignored.

19.2.6 URI Handling Functions

Uniform Resource Identifiers, or URIs, are Strings that identify resources (e.g. web pages or files) and transport protocols by which to access them (e.g. HTTP or FTP) on the Internet. The ECMAScript language itself does not provide any support for using URIs except for functions that encode and decode URIs as described in this section. encodeURI and decodeURI are intended to work with complete URIs; they assume that any reserved characters are intended to have special meaning (e.g., as delimiters) and so are not encoded. encodeURIComponent and decodeURIComponent are intended to work with the individual components of a URI; they assume that any reserved characters represent text and must be encoded to avoid special meaning when the component is part of a complete URI.

Note 1

The set of reserved characters is based upon RFC 2396 and does not reflect changes introduced by the more recent RFC 3986.

Note 2

Many implementations of ECMAScript provide additional functions and methods that manipulate web pages; these functions are beyond the scope of this standard.

19.2.6.1 decodeURI ( encodedURI )

This function computes a new version of a URI in which each escape sequence and UTF-8 encoding of the sort that might be introduced by the encodeURI function is replaced with the UTF-16 encoding of the code point that it represents. Escape sequences that could not have been introduced by encodeURI are not replaced.

It is the %decodeURI% intrinsic object.

It performs the following steps when called:

  1. Let uriString be ? ToString(encodedURI).
  2. Let preserveEscapeSet be ";/?:@&=+$,#".
  3. Return ? Decode(uriString, preserveEscapeSet).

19.2.6.2 decodeURIComponent ( encodedURIComponent )

This function computes a new version of a URI in which each escape sequence and UTF-8 encoding of the sort that might be introduced by the encodeURIComponent function is replaced with the UTF-16 encoding of the code point that it represents.

It is the %decodeURIComponent% intrinsic object.

It performs the following steps when called:

  1. Let componentString be ? ToString(encodedURIComponent).
  2. Let preserveEscapeSet be the empty String.
  3. Return ? Decode(componentString, preserveEscapeSet).

19.2.6.3 encodeURI ( uri )

This function computes a new version of a UTF-16 encoded (6.1.4) URI in which each instance of certain code points is replaced by one, two, three, or four escape sequences representing the UTF-8 encoding of the code point.

It is the %encodeURI% intrinsic object.

It performs the following steps when called:

  1. Let uriString be ? ToString(uri).
  2. Let extraUnescaped be ";/?:@&=+$,#".
  3. Return ? Encode(uriString, extraUnescaped).

19.2.6.4 encodeURIComponent ( uriComponent )

This function computes a new version of a UTF-16 encoded (6.1.4) URI in which each instance of certain code points is replaced by one, two, three, or four escape sequences representing the UTF-8 encoding of the code point.

It is the %encodeURIComponent% intrinsic object.

It performs the following steps when called:

  1. Let componentString be ? ToString(uriComponent).
  2. Let extraUnescaped be the empty String.
  3. Return ? Encode(componentString, extraUnescaped).

19.2.6.5 Encode ( string, extraUnescaped )

The abstract operation Encode takes arguments string (a String) and extraUnescaped (a String) and returns either a normal completion containing a String or a throw completion. It performs URI encoding and escaping, interpreting string as a sequence of UTF-16 encoded code points as described in 6.1.4. If a character is identified as unreserved in RFC 2396 or appears in extraUnescaped, it is not escaped. It performs the following steps when called:

  1. Let len be the length of string.
  2. Let R be the empty String.
  3. Let alwaysUnescaped be the string-concatenation of the ASCII word characters and "-.!~*'()".
  4. Let unescapedSet be the string-concatenation of alwaysUnescaped and extraUnescaped.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let C be the code unit at index k within string.
    2. If unescapedSet contains C, then
      1. Set k to k + 1.
      2. Set R to the string-concatenation of R and C.
    3. Else,
      1. Let cp be CodePointAt(string, k).
      2. If cp.[[IsUnpairedSurrogate]] is true, throw a URIError exception.
      3. Set k to k + cp.[[CodeUnitCount]].
      4. Let Octets be the List of octets resulting by applying the UTF-8 transformation to cp.[[CodePoint]].
      5. For each element octet of Octets, do
        1. Let hex be the String representation of octet, formatted as an uppercase hexadecimal number.
        2. Set R to the string-concatenation of R, "%", and StringPad(hex, 2, "0", start).
  7. Return R.
Note

Because percent-encoding is used to represent individual octets, a single code point may be expressed as multiple consecutive escape sequences (one for each of its 8-bit UTF-8 code units).

19.2.6.6 Decode ( string, preserveEscapeSet )

The abstract operation Decode takes arguments string (a String) and preserveEscapeSet (a String) and returns either a normal completion containing a String or a throw completion. It performs URI unescaping and decoding, preserving any escape sequences that correspond to Basic Latin characters in preserveEscapeSet. It performs the following steps when called:

  1. Let len be the length of string.
  2. Let R be the empty String.
  3. Let k be 0.
  4. Repeat, while k < len,
    1. Let C be the code unit at index k within string.
    2. Let S be C.
    3. If C is the code unit 0x0025 (PERCENT SIGN), then
      1. If k + 3 > len, throw a URIError exception.
      2. Let escape be the substring of string from k to k + 3.
      3. Let B be ParseHexOctet(string, k + 1).
      4. If B is not an integer, throw a URIError exception.
      5. Set k to k + 2.
      6. Let n be the number of leading 1 bits in B.
      7. If n = 0, then
        1. Let asciiChar be the code unit whose numeric value is B.
        2. If preserveEscapeSet contains asciiChar, set S to escape. Otherwise, set S to asciiChar.
      8. Else,
        1. If n = 1 or n > 4, throw a URIError exception.
        2. Let Octets be « B ».
        3. Let j be 1.
        4. Repeat, while j < n,
          1. Set k to k + 1.
          2. If k + 3 > len, throw a URIError exception.
          3. If the code unit at index k within string is not the code unit 0x0025 (PERCENT SIGN), throw a URIError exception.
          4. Let continuationByte be ParseHexOctet(string, k + 1).
          5. If continuationByte is not an integer, throw a URIError exception.
          6. Append continuationByte to Octets.
          7. Set k to k + 2.
          8. Set j to j + 1.
        5. Assert: The length of Octets is n.
        6. If Octets does not contain a valid UTF-8 encoding of a Unicode code point, throw a URIError exception.
        7. Let V be the code point obtained by applying the UTF-8 transformation to Octets, that is, from a List of octets into a 21-bit value.
        8. Set S to UTF16EncodeCodePoint(V).
    4. Set R to the string-concatenation of R and S.
    5. Set k to k + 1.
  5. Return R.
Note

RFC 3629 prohibits the decoding of invalid UTF-8 octet sequences. For example, the invalid sequence 0xC0 0x80 must not decode into the code unit 0x0000. Implementations of the Decode algorithm are required to throw a URIError when encountering such invalid sequences.

19.2.6.7 ParseHexOctet ( string, position )

The abstract operation ParseHexOctet takes arguments string (a String) and position (a non-negative integer) and returns either a non-negative integer or a non-empty List of SyntaxError objects. It parses a sequence of two hexadecimal characters at the specified position in string into an unsigned 8-bit integer. It performs the following steps when called:

  1. Let len be the length of string.
  2. Assert: position + 2 ≤ len.
  3. Let hexDigits be the substring of string from position to position + 2.
  4. Let parseResult be ParseText(StringToCodePoints(hexDigits), HexDigits[~Sep]).
  5. If parseResult is not a Parse Node, return parseResult.
  6. Let n be the MV of parseResult.
  7. Assert: n is in the inclusive interval from 0 to 255.
  8. Return n.

19.3 Constructor Properties of the Global Object

19.3.1 AggregateError ( . . . )

See 20.5.7.1.

19.3.2 Array ( . . . )

See 23.1.1.

19.3.3 ArrayBuffer ( . . . )

See 25.1.4.

19.3.4 BigInt ( . . . )

See 21.2.1.

19.3.5 BigInt64Array ( . . . )

See 23.2.5.

19.3.6 BigUint64Array ( . . . )

See 23.2.5.

19.3.7 Boolean ( . . . )

See 20.3.1.

19.3.8 DataView ( . . . )

See 25.3.2.

19.3.9 Date ( . . . )

See 21.4.2.

19.3.10 Error ( . . . )

See 20.5.1.

19.3.11 EvalError ( . . . )

See 20.5.5.1.

19.3.12 FinalizationRegistry ( . . . )

See 26.2.1.

19.3.13 Float32Array ( . . . )

See 23.2.5.

19.3.14 Float64Array ( . . . )

See 23.2.5.

19.3.15 Function ( . . . )

See 20.2.1.

19.3.16 Int8Array ( . . . )

See 23.2.5.

19.3.17 Int16Array ( . . . )

See 23.2.5.

19.3.18 Int32Array ( . . . )

See 23.2.5.

19.3.19 Map ( . . . )

See 24.1.1.

19.3.20 Number ( . . . )

See 21.1.1.

19.3.21 Object ( . . . )

See 20.1.1.

19.3.22 Promise ( . . . )

See 27.2.3.

19.3.23 Proxy ( . . . )

See 28.2.1.

19.3.24 RangeError ( . . . )

See 20.5.5.2.

19.3.25 ReferenceError ( . . . )

See 20.5.5.3.

19.3.26 RegExp ( . . . )

See 22.2.4.

19.3.27 Set ( . . . )

See 24.2.1.

19.3.28 SharedArrayBuffer ( . . . )

See 25.2.3.

19.3.29 String ( . . . )

See 22.1.1.

19.3.30 Symbol ( . . . )

See 20.4.1.

19.3.31 SyntaxError ( . . . )

See 20.5.5.4.

19.3.32 TypeError ( . . . )

See 20.5.5.5.

19.3.33 Uint8Array ( . . . )

See 23.2.5.

19.3.34 Uint8ClampedArray ( . . . )

See 23.2.5.

19.3.35 Uint16Array ( . . . )

See 23.2.5.

19.3.36 Uint32Array ( . . . )

See 23.2.5.

19.3.37 URIError ( . . . )

See 20.5.5.6.

19.3.38 WeakMap ( . . . )

See 24.3.1.

19.3.39 WeakRef ( . . . )

See 26.1.1.

19.3.40 WeakSet ( . . . )

See 24.4.

19.4 Other Properties of the Global Object

19.4.1 Atomics

See 25.4.

19.4.2 JSON

See 25.5.

19.4.3 Math

See 21.3.

19.4.4 Reflect

See 28.1.

20 Fundamental Objects

20.1 Object Objects

20.1.1 The Object Constructor

The Object constructor:

  • is %Object%.
  • is the initial value of the "Object" property of the global object.
  • creates a new ordinary object when called as a constructor.
  • performs a type conversion when called as a function rather than as a constructor.
  • may be used as the value of an extends clause of a class definition.

20.1.1.1 Object ( [ value ] )

This function performs the following steps when called:

  1. If NewTarget is neither undefined nor the active function object, then
    1. Return ? OrdinaryCreateFromConstructor(NewTarget, "%Object.prototype%").
  2. If value is either undefined or null, return OrdinaryObjectCreate(%Object.prototype%).
  3. Return ! ToObject(value).

20.1.2 Properties of the Object Constructor

The Object constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has a "length" property whose value is 1𝔽.
  • has the following additional properties:

20.1.2.1 Object.assign ( target, ...sources )

This function copies the values of all of the enumerable own properties from one or more source objects to a target object.

It performs the following steps when called:

  1. Let to be ? ToObject(target).
  2. If only one argument was passed, return to.
  3. For each element nextSource of sources, do
    1. If nextSource is neither undefined nor null, then
      1. Let from be ! ToObject(nextSource).
      2. Let keys be ? from.[[OwnPropertyKeys]]().
      3. For each element nextKey of keys, do
        1. Let desc be ? from.[[GetOwnProperty]](nextKey).
        2. If desc is not undefined and desc.[[Enumerable]] is true, then
          1. Let propValue be ? Get(from, nextKey).
          2. Perform ? Set(to, nextKey, propValue, true).
  4. Return to.

The "length" property of this function is 2𝔽.

20.1.2.2 Object.create ( O, Properties )

This function creates a new object with a specified prototype.

It performs the following steps when called:

  1. If O is not an Object and O is not null, throw a TypeError exception.
  2. Let obj be OrdinaryObjectCreate(O).
  3. If Properties is not undefined, then
    1. Return ? ObjectDefineProperties(obj, Properties).
  4. Return obj.

20.1.2.3 Object.defineProperties ( O, Properties )

This function adds own properties and/or updates the attributes of existing own properties of an object.

It performs the following steps when called:

  1. If O is not an Object, throw a TypeError exception.
  2. Return ? ObjectDefineProperties(O, Properties).

20.1.2.3.1 ObjectDefineProperties ( O, Properties )

The abstract operation ObjectDefineProperties takes arguments O (an Object) and Properties (an ECMAScript language value) and returns either a normal completion containing an Object or a throw completion. It performs the following steps when called:

  1. Let props be ? ToObject(Properties).
  2. Let keys be ? props.[[OwnPropertyKeys]]().
  3. Let descriptors be a new empty List.
  4. For each element nextKey of keys, do
    1. Let propDesc be ? props.[[GetOwnProperty]](nextKey).
    2. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then
      1. Let descObj be ? Get(props, nextKey).
      2. Let desc be ? ToPropertyDescriptor(descObj).
      3. Append the Record { [[Key]]: nextKey, [[Descriptor]]: desc } to descriptors.
  5. For each element property of descriptors, do
    1. Perform ? DefinePropertyOrThrow(O, property.[[Key]], property.[[Descriptor]]).
  6. Return O.

20.1.2.4 Object.defineProperty ( O, P, Attributes )

This function adds an own property and/or updates the attributes of an existing own property of an object.

It performs the following steps when called:

  1. If O is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(P).
  3. Let desc be ? ToPropertyDescriptor(Attributes).
  4. Perform ? DefinePropertyOrThrow(O, key, desc).
  5. Return O.

20.1.2.5 Object.entries ( O )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let entryList be ? EnumerableOwnProperties(obj, key+value).
  3. Return CreateArrayFromList(entryList).

20.1.2.6 Object.freeze ( O )

This function performs the following steps when called:

  1. If O is not an Object, return O.
  2. Let status be ? SetIntegrityLevel(O, frozen).
  3. If status is false, throw a TypeError exception.
  4. Return O.

20.1.2.7 Object.fromEntries ( iterable )

This function performs the following steps when called:

  1. Perform ? RequireObjectCoercible(iterable).
  2. Let obj be OrdinaryObjectCreate(%Object.prototype%).
  3. Assert: obj is an extensible ordinary object with no own properties.
  4. Let closure be a new Abstract Closure with parameters (key, value) that captures obj and performs the following steps when called:
    1. Let propertyKey be ? ToPropertyKey(key).
    2. Perform ! CreateDataPropertyOrThrow(obj, propertyKey, value).
    3. Return undefined.
  5. Let adder be CreateBuiltinFunction(closure, 2, "", « »).
  6. Return ? AddEntriesFromIterable(obj, iterable, adder).
Note
The function created for adder is never directly accessible to ECMAScript code.

20.1.2.8 Object.getOwnPropertyDescriptor ( O, P )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let key be ? ToPropertyKey(P).
  3. Let desc be ? obj.[[GetOwnProperty]](key).
  4. Return FromPropertyDescriptor(desc).

20.1.2.9 Object.getOwnPropertyDescriptors ( O )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let ownKeys be ? obj.[[OwnPropertyKeys]]().
  3. Let descriptors be OrdinaryObjectCreate(%Object.prototype%).
  4. For each element key of ownKeys, do
    1. Let desc be ? obj.[[GetOwnProperty]](key).
    2. Let descriptor be FromPropertyDescriptor(desc).
    3. If descriptor is not undefined, perform ! CreateDataPropertyOrThrow(descriptors, key, descriptor).
  5. Return descriptors.

20.1.2.10 Object.getOwnPropertyNames ( O )

This function performs the following steps when called:

  1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, string)).

20.1.2.11 Object.getOwnPropertySymbols ( O )

This function performs the following steps when called:

  1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, symbol)).

20.1.2.11.1 GetOwnPropertyKeys ( O, type )

The abstract operation GetOwnPropertyKeys takes arguments O (an ECMAScript language value) and type (string or symbol) and returns either a normal completion containing a List of property keys or a throw completion. It performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let keys be ? obj.[[OwnPropertyKeys]]().
  3. Let nameList be a new empty List.
  4. For each element nextKey of keys, do
    1. If nextKey is a Symbol and type is symbol, or if nextKey is a String and type is string, then
      1. Append nextKey to nameList.
  5. Return nameList.

20.1.2.12 Object.getPrototypeOf ( O )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Return ? obj.[[GetPrototypeOf]]().

20.1.2.13 Object.groupBy ( items, callbackfn )

Note

callbackfn should be a function that accepts two arguments. groupBy calls callbackfn once for each element in items, in ascending order, and constructs a new object. Each value returned by callbackfn is coerced to a property key. For each such property key, the result object has a property whose key is that property key and whose value is an array containing all the elements for which the callbackfn return value coerced to that key.

callbackfn is called with two arguments: the value of the element and the index of the element.

The return value of groupBy is an object that does not inherit from %Object.prototype%.

This function performs the following steps when called:

  1. Let groups be ? GroupBy(items, callbackfn, property).
  2. Let obj be OrdinaryObjectCreate(null).
  3. For each Record { [[Key]], [[Elements]] } g of groups, do
    1. Let elements be CreateArrayFromList(g.[[Elements]]).
    2. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements).
  4. Return obj.

20.1.2.14 Object.hasOwn ( O, P )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let key be ? ToPropertyKey(P).
  3. Return ? HasOwnProperty(obj, key).

20.1.2.15 Object.is ( value1, value2 )

This function performs the following steps when called:

  1. Return SameValue(value1, value2).

20.1.2.16 Object.isExtensible ( O )

This function performs the following steps when called:

  1. If O is not an Object, return false.
  2. Return ? IsExtensible(O).

20.1.2.17 Object.isFrozen ( O )

This function performs the following steps when called:

  1. If O is not an Object, return true.
  2. Return ? TestIntegrityLevel(O, frozen).

20.1.2.18 Object.isSealed ( O )

This function performs the following steps when called:

  1. If O is not an Object, return true.
  2. Return ? TestIntegrityLevel(O, sealed).

20.1.2.19 Object.keys ( O )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let keyList be ? EnumerableOwnProperties(obj, key).
  3. Return CreateArrayFromList(keyList).

20.1.2.20 Object.preventExtensions ( O )

This function performs the following steps when called:

  1. If O is not an Object, return O.
  2. Let status be ? O.[[PreventExtensions]]().
  3. If status is false, throw a TypeError exception.
  4. Return O.

20.1.2.21 Object.prototype

The initial value of Object.prototype is the Object prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.1.2.22 Object.seal ( O )

This function performs the following steps when called:

  1. If O is not an Object, return O.
  2. Let status be ? SetIntegrityLevel(O, sealed).
  3. If status is false, throw a TypeError exception.
  4. Return O.

20.1.2.23 Object.setPrototypeOf ( O, proto )

This function performs the following steps when called:

  1. Set O to ? RequireObjectCoercible(O).
  2. If proto is not an Object and proto is not null, throw a TypeError exception.
  3. If O is not an Object, return O.
  4. Let status be ? O.[[SetPrototypeOf]](proto).
  5. If status is false, throw a TypeError exception.
  6. Return O.

20.1.2.24 Object.values ( O )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let valueList be ? EnumerableOwnProperties(obj, value).
  3. Return CreateArrayFromList(valueList).

20.1.3 Properties of the Object Prototype Object

The Object prototype object:

  • is %Object.prototype%.
  • has an [[Extensible]] internal slot whose value is true.
  • has the internal methods defined for ordinary objects, except for the [[SetPrototypeOf]] method, which is as defined in 10.4.7.1. (Thus, it is an immutable prototype exotic object.)
  • has a [[Prototype]] internal slot whose value is null.

20.1.3.1 Object.prototype.constructor

The initial value of Object.prototype.constructor is %Object%.

20.1.3.2 Object.prototype.hasOwnProperty ( V )

This method performs the following steps when called:

  1. Let P be ? ToPropertyKey(V).
  2. Let O be ? ToObject(this value).
  3. Return ? HasOwnProperty(O, P).
Note

The ordering of steps 1 and 2 is chosen to ensure that any exception that would have been thrown by step 1 in previous editions of this specification will continue to be thrown even if the this value is undefined or null.

20.1.3.3 Object.prototype.isPrototypeOf ( V )

This method performs the following steps when called:

  1. If V is not an Object, return false.
  2. Let O be ? ToObject(this value).
  3. Repeat,
    1. Set V to ? V.[[GetPrototypeOf]]().
    2. If V is null, return false.
    3. If SameValue(O, V) is true, return true.
Note

The ordering of steps 1 and 2 preserves the behaviour specified by previous editions of this specification for the case where V is not an object and the this value is undefined or null.

20.1.3.4 Object.prototype.propertyIsEnumerable ( V )

This method performs the following steps when called:

  1. Let P be ? ToPropertyKey(V).
  2. Let O be ? ToObject(this value).
  3. Let desc be ? O.[[GetOwnProperty]](P).
  4. If desc is undefined, return false.
  5. Return desc.[[Enumerable]].
Note 1

This method does not consider objects in the prototype chain.

Note 2

The ordering of steps 1 and 2 is chosen to ensure that any exception that would have been thrown by step 1 in previous editions of this specification will continue to be thrown even if the this value is undefined or null.

20.1.3.5 Object.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Return ? Invoke(O, "toString").

The optional parameters to this method are not used but are intended to correspond to the parameter pattern used by ECMA-402 toLocaleString methods. Implementations that do not include ECMA-402 support must not use those parameter positions for other purposes.

Note 1

This method provides a generic toLocaleString implementation for objects that have no locale-sensitive toString behaviour. Array, Number, Date, and %TypedArray% provide their own locale-sensitive toLocaleString methods.

Note 2

ECMA-402 intentionally does not provide an alternative to this default implementation.

20.1.3.6 Object.prototype.toString ( )

This method performs the following steps when called:

  1. If the this value is undefined, return "[object Undefined]".
  2. If the this value is null, return "[object Null]".
  3. Let O be ! ToObject(this value).
  4. Let isArray be ? IsArray(O).
  5. If isArray is true, let builtinTag be "Array".
  6. Else if O has a [[ParameterMap]] internal slot, let builtinTag be "Arguments".
  7. Else if O has a [[Call]] internal method, let builtinTag be "Function".
  8. Else if O has an [[ErrorData]] internal slot, let builtinTag be "Error".
  9. Else if O has a [[BooleanData]] internal slot, let builtinTag be "Boolean".
  10. Else if O has a [[NumberData]] internal slot, let builtinTag be "Number".
  11. Else if O has a [[StringData]] internal slot, let builtinTag be "String".
  12. Else if O has a [[DateValue]] internal slot, let builtinTag be "Date".
  13. Else if O has a [[RegExpMatcher]] internal slot, let builtinTag be "RegExp".
  14. Else, let builtinTag be "Object".
  15. Let tag be ? Get(O, @@toStringTag).
  16. If tag is not a String, set tag to builtinTag.
  17. Return the string-concatenation of "[object ", tag, and "]".
Note

Historically, this method was occasionally used to access the String value of the [[Class]] internal slot that was used in previous editions of this specification as a nominal type tag for various built-in objects. The above definition of toString preserves compatibility for legacy code that uses toString as a test for those specific kinds of built-in objects. It does not provide a reliable type testing mechanism for other kinds of built-in or program defined objects. In addition, programs can use @@toStringTag in ways that will invalidate the reliability of such legacy type tests.

20.1.3.7 Object.prototype.valueOf ( )

This method performs the following steps when called:

  1. Return ? ToObject(this value).

20.1.3.8 Object.prototype.__proto__

Object.prototype.__proto__ is an accessor property with attributes { [[Enumerable]]: false, [[Configurable]]: true }. The [[Get]] and [[Set]] attributes are defined as follows:

20.1.3.8.1 get Object.prototype.__proto__

The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Return ? O.[[GetPrototypeOf]]().

20.1.3.8.2 set Object.prototype.__proto__

The value of the [[Set]] attribute is a built-in function that takes an argument proto. It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If proto is not an Object and proto is not null, return undefined.
  3. If O is not an Object, return undefined.
  4. Let status be ? O.[[SetPrototypeOf]](proto).
  5. If status is false, throw a TypeError exception.
  6. Return undefined.

20.1.3.9 Legacy Object.prototype Accessor Methods

20.1.3.9.1 Object.prototype.__defineGetter__ ( P, getter )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. If IsCallable(getter) is false, throw a TypeError exception.
  3. Let desc be PropertyDescriptor { [[Get]]: getter, [[Enumerable]]: true, [[Configurable]]: true }.
  4. Let key be ? ToPropertyKey(P).
  5. Perform ? DefinePropertyOrThrow(O, key, desc).
  6. Return undefined.

20.1.3.9.2 Object.prototype.__defineSetter__ ( P, setter )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. If IsCallable(setter) is false, throw a TypeError exception.
  3. Let desc be PropertyDescriptor { [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: true }.
  4. Let key be ? ToPropertyKey(P).
  5. Perform ? DefinePropertyOrThrow(O, key, desc).
  6. Return undefined.

20.1.3.9.3 Object.prototype.__lookupGetter__ ( P )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let key be ? ToPropertyKey(P).
  3. Repeat,
    1. Let desc be ? O.[[GetOwnProperty]](key).
    2. If desc is not undefined, then
      1. If IsAccessorDescriptor(desc) is true, return desc.[[Get]].
      2. Return undefined.
    3. Set O to ? O.[[GetPrototypeOf]]().
    4. If O is null, return undefined.

20.1.3.9.4 Object.prototype.__lookupSetter__ ( P )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let key be ? ToPropertyKey(P).
  3. Repeat,
    1. Let desc be ? O.[[GetOwnProperty]](key).
    2. If desc is not undefined, then
      1. If IsAccessorDescriptor(desc) is true, return desc.[[Set]].
      2. Return undefined.
    3. Set O to ? O.[[GetPrototypeOf]]().
    4. If O is null, return undefined.

20.1.4 Properties of Object Instances

Object instances have no special properties beyond those inherited from the Object prototype object.

20.2 Function Objects

20.2.1 The Function Constructor

The Function constructor:

  • is %Function%.
  • is the initial value of the "Function" property of the global object.
  • creates and initializes a new function object when called as a function rather than as a constructor. Thus the function call Function(…) is equivalent to the object creation expression new Function(…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Function behaviour must include a super call to the Function constructor to create and initialize a subclass instance with the internal slots necessary for built-in function behaviour. All ECMAScript syntactic forms for defining function objects create instances of Function. There is no syntactic means to create instances of Function subclasses except for the built-in GeneratorFunction, AsyncFunction, and AsyncGeneratorFunction subclasses.

20.2.1.1 Function ( ...parameterArgs, bodyArg )

The last argument (if any) specifies the body (executable code) of a function; any preceding arguments specify formal parameters.

This function performs the following steps when called:

  1. Let C be the active function object.
  2. If bodyArg is not present, set bodyArg to the empty String.
  3. Return ? CreateDynamicFunction(C, NewTarget, normal, parameterArgs, bodyArg).
Note

It is permissible but not necessary to have one argument for each formal parameter to be specified. For example, all three of the following expressions produce the same result:

new Function("a", "b", "c", "return a+b+c")
new Function("a, b, c", "return a+b+c")
new Function("a,b", "c", "return a+b+c")

20.2.1.1.1 CreateDynamicFunction ( constructor, newTarget, kind, parameterArgs, bodyArg )

The abstract operation CreateDynamicFunction takes arguments constructor (a constructor), newTarget (a constructor), kind (normal, generator, async, or async-generator), parameterArgs (a List of ECMAScript language values), and bodyArg (an ECMAScript language value) and returns either a normal completion containing an ECMAScript function object or a throw completion. constructor is the constructor function that is performing this action. newTarget is the constructor that new was initially applied to. parameterArgs and bodyArg reflect the argument values that were passed to constructor. It performs the following steps when called:

  1. If newTarget is undefined, set newTarget to constructor.
  2. If kind is normal, then
    1. Let prefix be "function".
    2. Let exprSym be the grammar symbol FunctionExpression.
    3. Let bodySym be the grammar symbol FunctionBody[~Yield, ~Await].
    4. Let parameterSym be the grammar symbol FormalParameters[~Yield, ~Await].
    5. Let fallbackProto be "%Function.prototype%".
  3. Else if kind is generator, then
    1. Let prefix be "function*".
    2. Let exprSym be the grammar symbol GeneratorExpression.
    3. Let bodySym be the grammar symbol GeneratorBody.
    4. Let parameterSym be the grammar symbol FormalParameters[+Yield, ~Await].
    5. Let fallbackProto be "%GeneratorFunction.prototype%".
  4. Else if kind is async, then
    1. Let prefix be "async function".
    2. Let exprSym be the grammar symbol AsyncFunctionExpression.
    3. Let bodySym be the grammar symbol AsyncFunctionBody.
    4. Let parameterSym be the grammar symbol FormalParameters[~Yield, +Await].
    5. Let fallbackProto be "%AsyncFunction.prototype%".
  5. Else,
    1. Assert: kind is async-generator.
    2. Let prefix be "async function*".
    3. Let exprSym be the grammar symbol AsyncGeneratorExpression.
    4. Let bodySym be the grammar symbol AsyncGeneratorBody.
    5. Let parameterSym be the grammar symbol FormalParameters[+Yield, +Await].
    6. Let fallbackProto be "%AsyncGeneratorFunction.prototype%".
  6. Let argCount be the number of elements in parameterArgs.
  7. Let bodyString be ? ToString(bodyArg).
  8. Let parameterStrings be a new empty List.
  9. For each element arg of parameterArgs, do
    1. Append ? ToString(arg) to parameterStrings.
  10. Let currentRealm be the current Realm Record.
  11. Perform ? HostEnsureCanCompileStrings(currentRealm, parameterStrings, bodyString, false).
  12. Let P be the empty String.
  13. If argCount > 0, then
    1. Set P to parameterStrings[0].
    2. Let k be 1.
    3. Repeat, while k < argCount,
      1. Let nextArgString be parameterStrings[k].
      2. Set P to the string-concatenation of P, "," (a comma), and nextArgString.
      3. Set k to k + 1.
  14. Let bodyParseString be the string-concatenation of 0x000A (LINE FEED), bodyString, and 0x000A (LINE FEED).
  15. Let sourceString be the string-concatenation of prefix, " anonymous(", P, 0x000A (LINE FEED), ") {", bodyParseString, and "}".
  16. Let sourceText be StringToCodePoints(sourceString).
  17. Let parameters be ParseText(StringToCodePoints(P), parameterSym).
  18. If parameters is a List of errors, throw a SyntaxError exception.
  19. Let body be ParseText(StringToCodePoints(bodyParseString), bodySym).
  20. If body is a List of errors, throw a SyntaxError exception.
  21. NOTE: The parameters and body are parsed separately to ensure that each is valid alone. For example, new Function("/*", "*/ ) {") does not evaluate to a function.
  22. NOTE: If this step is reached, sourceText must have the syntax of exprSym (although the reverse implication does not hold). The purpose of the next two steps is to enforce any Early Error rules which apply to exprSym directly.
  23. Let expr be ParseText(sourceText, exprSym).
  24. If expr is a List of errors, throw a SyntaxError exception.
  25. Let proto be ? GetPrototypeFromConstructor(newTarget, fallbackProto).
  26. Let env be currentRealm.[[GlobalEnv]].
  27. Let privateEnv be null.
  28. Let F be OrdinaryFunctionCreate(proto, sourceText, parameters, body, non-lexical-this, env, privateEnv).
  29. Perform SetFunctionName(F, "anonymous").
  30. If kind is generator, then
    1. Let prototype be OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
    2. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  31. Else if kind is async-generator, then
    1. Let prototype be OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
    2. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  32. Else if kind is normal, then
    1. Perform MakeConstructor(F).
  33. NOTE: Functions whose kind is async are not constructible and do not have a [[Construct]] internal method or a "prototype" property.
  34. Return F.
Note

CreateDynamicFunction defines a "prototype" property on any function it creates whose kind is not async to provide for the possibility that the function will be used as a constructor.

20.2.2 Properties of the Function Constructor

The Function constructor:

  • is itself a built-in function object.
  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has a "length" property whose value is 1𝔽.
  • has the following properties:

20.2.2.1 Function.prototype

The value of Function.prototype is the Function prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.2.3 Properties of the Function Prototype Object

The Function prototype object:

  • is %Function.prototype%.
  • is itself a built-in function object.
  • accepts any arguments and returns undefined when invoked.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • does not have a "prototype" property.
  • has a "length" property whose value is +0𝔽.
  • has a "name" property whose value is the empty String.
Note

The Function prototype object is specified to be a function object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.

20.2.3.1 Function.prototype.apply ( thisArg, argArray )

This method performs the following steps when called:

  1. Let func be the this value.
  2. If IsCallable(func) is false, throw a TypeError exception.
  3. If argArray is either undefined or null, then
    1. Perform PrepareForTailCall().
    2. Return ? Call(func, thisArg).
  4. Let argList be ? CreateListFromArrayLike(argArray).
  5. Perform PrepareForTailCall().
  6. Return ? Call(func, thisArg, argList).
Note 1

The thisArg value is passed without modification as the this value. This is a change from Edition 3, where an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value. Even though the thisArg is passed without modification, non-strict functions still perform these transformations upon entry to the function.

Note 2

If func is either an arrow function or a bound function exotic object, then the thisArg will be ignored by the function [[Call]] in step 6.

20.2.3.2 Function.prototype.bind ( thisArg, ...args )

This method performs the following steps when called:

  1. Let Target be the this value.
  2. If IsCallable(Target) is false, throw a TypeError exception.
  3. Let F be ? BoundFunctionCreate(Target, thisArg, args).
  4. Let L be 0.
  5. Let targetHasLength be ? HasOwnProperty(Target, "length").
  6. If targetHasLength is true, then
    1. Let targetLen be ? Get(Target, "length").
    2. If targetLen is a Number, then
      1. If targetLen is +∞𝔽, then
        1. Set L to +∞.
      2. Else if targetLen is -∞𝔽, then
        1. Set L to 0.
      3. Else,
        1. Let targetLenAsInt be ! ToIntegerOrInfinity(targetLen).
        2. Assert: targetLenAsInt is finite.
        3. Let argCount be the number of elements in args.
        4. Set L to max(targetLenAsInt - argCount, 0).
  7. Perform SetFunctionLength(F, L).
  8. Let targetName be ? Get(Target, "name").
  9. If targetName is not a String, set targetName to the empty String.
  10. Perform SetFunctionName(F, targetName, "bound").
  11. Return F.
Note 1

Function objects created using Function.prototype.bind are exotic objects. They also do not have a "prototype" property.

Note 2

If Target is either an arrow function or a bound function exotic object, then the thisArg passed to this method will not be used by subsequent calls to F.

20.2.3.3 Function.prototype.call ( thisArg, ...args )

This method performs the following steps when called:

  1. Let func be the this value.
  2. If IsCallable(func) is false, throw a TypeError exception.
  3. Perform PrepareForTailCall().
  4. Return ? Call(func, thisArg, args).
Note 1

The thisArg value is passed without modification as the this value. This is a change from Edition 3, where an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value. Even though the thisArg is passed without modification, non-strict functions still perform these transformations upon entry to the function.

Note 2

If func is either an arrow function or a bound function exotic object, then the thisArg will be ignored by the function [[Call]] in step 4.

20.2.3.4 Function.prototype.constructor

The initial value of Function.prototype.constructor is %Function%.

20.2.3.5 Function.prototype.toString ( )

This method performs the following steps when called:

  1. Let func be the this value.
  2. If func is an Object, func has a [[SourceText]] internal slot, func.[[SourceText]] is a sequence of Unicode code points, and HostHasSourceTextAvailable(func) is true, then
    1. Return CodePointsToString(func.[[SourceText]]).
  3. If func is a built-in function object, return an implementation-defined String source code representation of func. The representation must have the syntax of a NativeFunction. Additionally, if func has an [[InitialName]] internal slot and func.[[InitialName]] is a String, the portion of the returned String that would be matched by NativeFunctionAccessoropt PropertyName must be the value of func.[[InitialName]].
  4. If func is an Object and IsCallable(func) is true, return an implementation-defined String source code representation of func. The representation must have the syntax of a NativeFunction.
  5. Throw a TypeError exception.
NativeFunction : function NativeFunctionAccessoropt PropertyName[~Yield, ~Await]opt ( FormalParameters[~Yield, ~Await] ) { [ native code ] } NativeFunctionAccessor : get set

20.2.3.6 Function.prototype [ @@hasInstance ] ( V )

This method performs the following steps when called:

  1. Let F be the this value.
  2. Return ? OrdinaryHasInstance(F, V).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

This is the default implementation of @@hasInstance that most functions inherit. @@hasInstance is called by the instanceof operator to determine whether a value is an instance of a specific constructor. An expression such as

v instanceof F

evaluates as

F[@@hasInstance](v)

A constructor function can control which objects are recognized as its instances by instanceof by exposing a different @@hasInstance method on the function.

This property is non-writable and non-configurable to prevent tampering that could be used to globally expose the target function of a bound function.

The value of the "name" property of this method is "[Symbol.hasInstance]".

20.2.4 Function Instances

Every Function instance is an ECMAScript function object and has the internal slots listed in Table 30. Function objects created using the Function.prototype.bind method (20.2.3.2) have the internal slots listed in Table 31.

Function instances have the following properties:

20.2.4.1 length

The value of the "length" property is an integral Number that indicates the typical number of arguments expected by the function. However, the language permits the function to be invoked with some other number of arguments. The behaviour of a function when invoked on a number of arguments other than the number specified by its "length" property depends on the function. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

20.2.4.2 name

The value of the "name" property is a String that is descriptive of the function. The name has no semantic significance but is typically a variable or property name that is used to refer to the function at its point of definition in ECMAScript source text. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Anonymous functions objects that do not have a contextual name associated with them by this specification use the empty String as the value of the "name" property.

20.2.4.3 prototype

Function instances that can be used as a constructor have a "prototype" property. Whenever such a Function instance is created another ordinary object is also created and is the initial value of the function's "prototype" property. Unless otherwise specified, the value of the "prototype" property is used to initialize the [[Prototype]] internal slot of the object created when that function is invoked as a constructor.

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Function objects created using Function.prototype.bind, or by evaluating a MethodDefinition (that is not a GeneratorMethod or AsyncGeneratorMethod) or an ArrowFunction do not have a "prototype" property.

20.2.5 HostHasSourceTextAvailable ( func )

The host-defined abstract operation HostHasSourceTextAvailable takes argument func (a function object) and returns a Boolean. It allows host environments to prevent the source text from being provided for func.

An implementation of HostHasSourceTextAvailable must conform to the following requirements:

  • It must be deterministic with respect to its parameters. Each time it is called with a specific func as its argument, it must return the same result.

The default implementation of HostHasSourceTextAvailable is to return true.

20.3 Boolean Objects

20.3.1 The Boolean Constructor

The Boolean constructor:

  • is %Boolean%.
  • is the initial value of the "Boolean" property of the global object.
  • creates and initializes a new Boolean object when called as a constructor.
  • performs a type conversion when called as a function rather than as a constructor.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Boolean behaviour must include a super call to the Boolean constructor to create and initialize the subclass instance with a [[BooleanData]] internal slot.

20.3.1.1 Boolean ( value )

This function performs the following steps when called:

  1. Let b be ToBoolean(value).
  2. If NewTarget is undefined, return b.
  3. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Boolean.prototype%", « [[BooleanData]] »).
  4. Set O.[[BooleanData]] to b.
  5. Return O.

20.3.2 Properties of the Boolean Constructor

The Boolean constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

20.3.2.1 Boolean.prototype

The initial value of Boolean.prototype is the Boolean prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.3.3 Properties of the Boolean Prototype Object

The Boolean prototype object:

  • is %Boolean.prototype%.
  • is an ordinary object.
  • is itself a Boolean object; it has a [[BooleanData]] internal slot with the value false.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.

20.3.3.1 Boolean.prototype.constructor

The initial value of Boolean.prototype.constructor is %Boolean%.

20.3.3.2 Boolean.prototype.toString ( )

This method performs the following steps when called:

  1. Let b be ? ThisBooleanValue(this value).
  2. If b is true, return "true"; else return "false".

20.3.3.3 Boolean.prototype.valueOf ( )

This method performs the following steps when called:

  1. Return ? ThisBooleanValue(this value).

20.3.3.3.1 ThisBooleanValue ( value )

The abstract operation ThisBooleanValue takes argument value (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. If value is a Boolean, return value.
  2. If value is an Object and value has a [[BooleanData]] internal slot, then
    1. Let b be value.[[BooleanData]].
    2. Assert: b is a Boolean.
    3. Return b.
  3. Throw a TypeError exception.

20.3.4 Properties of Boolean Instances

Boolean instances are ordinary objects that inherit properties from the Boolean prototype object. Boolean instances have a [[BooleanData]] internal slot. The [[BooleanData]] internal slot is the Boolean value represented by this Boolean object.

20.4 Symbol Objects

20.4.1 The Symbol Constructor

The Symbol constructor:

  • is %Symbol%.
  • is the initial value of the "Symbol" property of the global object.
  • returns a new Symbol value when called as a function.
  • is not intended to be used with the new operator.
  • is not intended to be subclassed.
  • may be used as the value of an extends clause of a class definition but a super call to it will cause an exception.

20.4.1.1 Symbol ( [ description ] )

This function performs the following steps when called:

  1. If NewTarget is not undefined, throw a TypeError exception.
  2. If description is undefined, let descString be undefined.
  3. Else, let descString be ? ToString(description).
  4. Return a new Symbol whose [[Description]] is descString.

20.4.2 Properties of the Symbol Constructor

The Symbol constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

20.4.2.1 Symbol.asyncIterator

The initial value of Symbol.asyncIterator is the well known symbol @@asyncIterator (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.2 Symbol.for ( key )

This function performs the following steps when called:

  1. Let stringKey be ? ToString(key).
  2. For each element e of the GlobalSymbolRegistry List, do
    1. If SameValue(e.[[Key]], stringKey) is true, return e.[[Symbol]].
  3. Assert: GlobalSymbolRegistry does not currently contain an entry for stringKey.
  4. Let newSymbol be a new Symbol whose [[Description]] is stringKey.
  5. Append the Record { [[Key]]: stringKey, [[Symbol]]: newSymbol } to the GlobalSymbolRegistry List.
  6. Return newSymbol.

The GlobalSymbolRegistry is an append-only List that is globally available. It is shared by all realms. Prior to the evaluation of any ECMAScript code, it is initialized as a new empty List. Elements of the GlobalSymbolRegistry are Records with the structure defined in Table 60.

Table 60: GlobalSymbolRegistry Record Fields
Field Name Value Usage
[[Key]] a String A string key used to globally identify a Symbol.
[[Symbol]] a Symbol A symbol that can be retrieved from any realm.

20.4.2.3 Symbol.hasInstance

The initial value of Symbol.hasInstance is the well-known symbol @@hasInstance (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.4 Symbol.isConcatSpreadable

The initial value of Symbol.isConcatSpreadable is the well-known symbol @@isConcatSpreadable (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.5 Symbol.iterator

The initial value of Symbol.iterator is the well-known symbol @@iterator (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.6 Symbol.keyFor ( sym )

This function performs the following steps when called:

  1. If sym is not a Symbol, throw a TypeError exception.
  2. Return KeyForSymbol(sym).

20.4.2.7 Symbol.match

The initial value of Symbol.match is the well-known symbol @@match (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.8 Symbol.matchAll

The initial value of Symbol.matchAll is the well-known symbol @@matchAll (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.9 Symbol.prototype

The initial value of Symbol.prototype is the Symbol prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.10 Symbol.replace

The initial value of Symbol.replace is the well-known symbol @@replace (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.11 Symbol.search

The initial value of Symbol.search is the well-known symbol @@search (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.12 Symbol.species

The initial value of Symbol.species is the well-known symbol @@species (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.13 Symbol.split

The initial value of Symbol.split is the well-known symbol @@split (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.14 Symbol.toPrimitive

The initial value of Symbol.toPrimitive is the well-known symbol @@toPrimitive (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.15 Symbol.toStringTag

The initial value of Symbol.toStringTag is the well-known symbol @@toStringTag (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.16 Symbol.unscopables

The initial value of Symbol.unscopables is the well-known symbol @@unscopables (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.3 Properties of the Symbol Prototype Object

The Symbol prototype object:

20.4.3.1 Symbol.prototype.constructor

The initial value of Symbol.prototype.constructor is %Symbol%.

20.4.3.2 get Symbol.prototype.description

Symbol.prototype.description is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let s be the this value.
  2. Let sym be ? ThisSymbolValue(s).
  3. Return sym.[[Description]].

20.4.3.3 Symbol.prototype.toString ( )

This method performs the following steps when called:

  1. Let sym be ? ThisSymbolValue(this value).
  2. Return SymbolDescriptiveString(sym).

20.4.3.3.1 SymbolDescriptiveString ( sym )

The abstract operation SymbolDescriptiveString takes argument sym (a Symbol) and returns a String. It performs the following steps when called:

  1. Let desc be sym's [[Description]] value.
  2. If desc is undefined, set desc to the empty String.
  3. Assert: desc is a String.
  4. Return the string-concatenation of "Symbol(", desc, and ")".

20.4.3.4 Symbol.prototype.valueOf ( )

This method performs the following steps when called:

  1. Return ? ThisSymbolValue(this value).

20.4.3.4.1 ThisSymbolValue ( value )

The abstract operation ThisSymbolValue takes argument value (an ECMAScript language value) and returns either a normal completion containing a Symbol or a throw completion. It performs the following steps when called:

  1. If value is a Symbol, return value.
  2. If value is an Object and value has a [[SymbolData]] internal slot, then
    1. Let s be value.[[SymbolData]].
    2. Assert: s is a Symbol.
    3. Return s.
  3. Throw a TypeError exception.

20.4.3.5 Symbol.prototype [ @@toPrimitive ] ( hint )

This method is called by ECMAScript language operators to convert a Symbol object to a primitive value.

It performs the following steps when called:

  1. Return ? ThisSymbolValue(this value).
Note

The argument is ignored.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

The value of the "name" property of this method is "[Symbol.toPrimitive]".

20.4.3.6 Symbol.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Symbol".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

20.4.4 Properties of Symbol Instances

Symbol instances are ordinary objects that inherit properties from the Symbol prototype object. Symbol instances have a [[SymbolData]] internal slot. The [[SymbolData]] internal slot is the Symbol value represented by this Symbol object.

20.4.5 Abstract Operations for Symbols

20.4.5.1 KeyForSymbol ( sym )

The abstract operation KeyForSymbol takes argument sym (a Symbol) and returns a String or undefined. If sym is in the GlobalSymbolRegistry (see 20.4.2.2) the String used to register sym will be returned. It performs the following steps when called:

  1. For each element e of the GlobalSymbolRegistry List, do
    1. If SameValue(e.[[Symbol]], sym) is true, return e.[[Key]].
  2. Assert: GlobalSymbolRegistry does not currently contain an entry for sym.
  3. Return undefined.

20.5 Error Objects

Instances of Error objects are thrown as exceptions when runtime errors occur. The Error objects may also serve as base objects for user-defined exception classes.

When an ECMAScript implementation detects a runtime error, it throws a new instance of one of the NativeError objects defined in 20.5.5 or a new instance of AggregateError object defined in 20.5.7. Each of these objects has the structure described below, differing only in the name used as the constructor name instead of NativeError, in the "name" property of the prototype object, in the implementation-defined "message" property of the prototype object, and in the presence of the %AggregateError%-specific "errors" property.

20.5.1 The Error Constructor

The Error constructor:

  • is %Error%.
  • is the initial value of the "Error" property of the global object.
  • creates and initializes a new Error object when called as a function rather than as a constructor. Thus the function call Error(…) is equivalent to the object creation expression new Error(…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Error behaviour must include a super call to the Error constructor to create and initialize subclass instances with an [[ErrorData]] internal slot.

20.5.1.1 Error ( message [ , options ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
  2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%Error.prototype%", « [[ErrorData]] »).
  3. If message is not undefined, then
    1. Let msg be ? ToString(message).
    2. Perform CreateNonEnumerableDataPropertyOrThrow(O, "message", msg).
  4. Perform ? InstallErrorCause(O, options).
  5. Return O.

20.5.2 Properties of the Error Constructor

The Error constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

20.5.2.1 Error.prototype

The initial value of Error.prototype is the Error prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.5.3 Properties of the Error Prototype Object

The Error prototype object:

  • is %Error.prototype%.
  • is an ordinary object.
  • is not an Error instance and does not have an [[ErrorData]] internal slot.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.

20.5.3.1 Error.prototype.constructor

The initial value of Error.prototype.constructor is %Error%.

20.5.3.2 Error.prototype.message

The initial value of Error.prototype.message is the empty String.

20.5.3.3 Error.prototype.name

The initial value of Error.prototype.name is "Error".

20.5.3.4 Error.prototype.toString ( )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let name be ? Get(O, "name").
  4. If name is undefined, set name to "Error"; otherwise set name to ? ToString(name).
  5. Let msg be ? Get(O, "message").
  6. If msg is undefined, set msg to the empty String; otherwise set msg to ? ToString(msg).
  7. If name is the empty String, return msg.
  8. If msg is the empty String, return name.
  9. Return the string-concatenation of name, the code unit 0x003A (COLON), the code unit 0x0020 (SPACE), and msg.

20.5.4 Properties of Error Instances

Error instances are ordinary objects that inherit properties from the Error prototype object and have an [[ErrorData]] internal slot whose value is undefined. The only specified uses of [[ErrorData]] is to identify Error, AggregateError, and NativeError instances as Error objects within Object.prototype.toString.

20.5.5 Native Error Types Used in This Standard

A new instance of one of the NativeError objects below or of the AggregateError object is thrown when a runtime error is detected. All NativeError objects share the same structure, as described in 20.5.6.

20.5.5.1 EvalError

The EvalError constructor is %EvalError%.

This exception is not currently used within this specification. This object remains for compatibility with previous editions of this specification.

20.5.5.2 RangeError

The RangeError constructor is %RangeError%.

Indicates a value that is not in the set or range of allowable values.

20.5.5.3 ReferenceError

The ReferenceError constructor is %ReferenceError%.

Indicate that an invalid reference has been detected.

20.5.5.4 SyntaxError

The SyntaxError constructor is %SyntaxError%.

Indicates that a parsing error has occurred.

20.5.5.5 TypeError

The TypeError constructor is %TypeError%.

TypeError is used to indicate an unsuccessful operation when none of the other NativeError objects are an appropriate indication of the failure cause.

20.5.5.6 URIError

The URIError constructor is %URIError%.

Indicates that one of the global URI handling functions was used in a way that is incompatible with its definition.

20.5.6 NativeError Object Structure

When an ECMAScript implementation detects a runtime error, it throws a new instance of one of the NativeError objects defined in 20.5.5. Each of these objects has the structure described below, differing only in the name used as the constructor name instead of NativeError, in the "name" property of the prototype object, and in the implementation-defined "message" property of the prototype object.

For each error object, references to NativeError in the definition should be replaced with the appropriate error object name from 20.5.5.

20.5.6.1 The NativeError Constructors

Each NativeError constructor:

  • creates and initializes a new NativeError object when called as a function rather than as a constructor. A call of the object as a function is equivalent to calling it as a constructor with the same arguments. Thus the function call NativeError(…) is equivalent to the object creation expression new NativeError(…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified NativeError behaviour must include a super call to the NativeError constructor to create and initialize subclass instances with an [[ErrorData]] internal slot.

20.5.6.1.1 NativeError ( message [ , options ] )

Each NativeError function performs the following steps when called:

  1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
  2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%NativeError.prototype%", « [[ErrorData]] »).
  3. If message is not undefined, then
    1. Let msg be ? ToString(message).
    2. Perform CreateNonEnumerableDataPropertyOrThrow(O, "message", msg).
  4. Perform ? InstallErrorCause(O, options).
  5. Return O.

The actual value of the string passed in step 2 is either "%EvalError.prototype%", "%RangeError.prototype%", "%ReferenceError.prototype%", "%SyntaxError.prototype%", "%TypeError.prototype%", or "%URIError.prototype%" corresponding to which NativeError constructor is being defined.

20.5.6.2 Properties of the NativeError Constructors

Each NativeError constructor:

  • has a [[Prototype]] internal slot whose value is %Error%.
  • has a "name" property whose value is the String value "NativeError".
  • has the following properties:

20.5.6.2.1 NativeError.prototype

The initial value of NativeError.prototype is a NativeError prototype object (20.5.6.3). Each NativeError constructor has a distinct prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.5.6.3 Properties of the NativeError Prototype Objects

Each NativeError prototype object:

  • is an ordinary object.
  • is not an Error instance and does not have an [[ErrorData]] internal slot.
  • has a [[Prototype]] internal slot whose value is %Error.prototype%.

20.5.6.3.1 NativeError.prototype.constructor

The initial value of the "constructor" property of the prototype for a given NativeError constructor is the constructor itself.

20.5.6.3.2 NativeError.prototype.message

The initial value of the "message" property of the prototype for a given NativeError constructor is the empty String.

20.5.6.3.3 NativeError.prototype.name

The initial value of the "name" property of the prototype for a given NativeError constructor is the String value consisting of the name of the constructor (the name used instead of NativeError).

20.5.6.4 Properties of NativeError Instances

NativeError instances are ordinary objects that inherit properties from their NativeError prototype object and have an [[ErrorData]] internal slot whose value is undefined. The only specified use of [[ErrorData]] is by Object.prototype.toString (20.1.3.6) to identify Error, AggregateError, or NativeError instances.

20.5.7 AggregateError Objects

20.5.7.1 The AggregateError Constructor

The AggregateError constructor:

  • is %AggregateError%.
  • is the initial value of the "AggregateError" property of the global object.
  • creates and initializes a new AggregateError object when called as a function rather than as a constructor. Thus the function call AggregateError(…) is equivalent to the object creation expression new AggregateError(…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified AggregateError behaviour must include a super call to the AggregateError constructor to create and initialize subclass instances with an [[ErrorData]] internal slot.

20.5.7.1.1 AggregateError ( errors, message [ , options ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
  2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%AggregateError.prototype%", « [[ErrorData]] »).
  3. If message is not undefined, then
    1. Let msg be ? ToString(message).
    2. Perform CreateNonEnumerableDataPropertyOrThrow(O, "message", msg).
  4. Perform ? InstallErrorCause(O, options).
  5. Let errorsList be ? IteratorToList(? GetIterator(errors, sync)).
  6. Perform ! DefinePropertyOrThrow(O, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errorsList) }).
  7. Return O.

20.5.7.2 Properties of the AggregateError Constructor

The AggregateError constructor:

  • has a [[Prototype]] internal slot whose value is %Error%.
  • has the following properties:

20.5.7.2.1 AggregateError.prototype

The initial value of AggregateError.prototype is %AggregateError.prototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.5.7.3 Properties of the AggregateError Prototype Object

The AggregateError prototype object:

  • is %AggregateError.prototype%.
  • is an ordinary object.
  • is not an Error instance or an AggregateError instance and does not have an [[ErrorData]] internal slot.
  • has a [[Prototype]] internal slot whose value is %Error.prototype%.

20.5.7.3.1 AggregateError.prototype.constructor

The initial value of AggregateError.prototype.constructor is %AggregateError%.

20.5.7.3.2 AggregateError.prototype.message

The initial value of AggregateError.prototype.message is the empty String.

20.5.7.3.3 AggregateError.prototype.name

The initial value of AggregateError.prototype.name is "AggregateError".

20.5.7.4 Properties of AggregateError Instances

AggregateError instances are ordinary objects that inherit properties from their AggregateError prototype object and have an [[ErrorData]] internal slot whose value is undefined. The only specified use of [[ErrorData]] is by Object.prototype.toString (20.1.3.6) to identify Error, AggregateError, or NativeError instances.

20.5.8 Abstract Operations for Error Objects

20.5.8.1 InstallErrorCause ( O, options )

The abstract operation InstallErrorCause takes arguments O (an Object) and options (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. It is used to create a "cause" property on O when a "cause" property is present on options. It performs the following steps when called:

  1. If options is an Object and ? HasProperty(options, "cause") is true, then
    1. Let cause be ? Get(options, "cause").
    2. Perform CreateNonEnumerableDataPropertyOrThrow(O, "cause", cause).
  2. Return unused.

21 Numbers and Dates

21.1 Number Objects

21.1.1 The Number Constructor

The Number constructor:

  • is %Number%.
  • is the initial value of the "Number" property of the global object.
  • creates and initializes a new Number object when called as a constructor.
  • performs a type conversion when called as a function rather than as a constructor.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Number behaviour must include a super call to the Number constructor to create and initialize the subclass instance with a [[NumberData]] internal slot.

21.1.1.1 Number ( value )

This function performs the following steps when called:

  1. If value is present, then
    1. Let prim be ? ToNumeric(value).
    2. If prim is a BigInt, let n be 𝔽((prim)).
    3. Otherwise, let n be prim.
  2. Else,
    1. Let n be +0𝔽.
  3. If NewTarget is undefined, return n.
  4. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Number.prototype%", « [[NumberData]] »).
  5. Set O.[[NumberData]] to n.
  6. Return O.

21.1.2 Properties of the Number Constructor

The Number constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

21.1.2.1 Number.EPSILON

The value of Number.EPSILON is the Number value for the magnitude of the difference between 1 and the smallest value greater than 1 that is representable as a Number value, which is approximately 2.2204460492503130808472633361816 × 10-16.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.2 Number.isFinite ( number )

This function performs the following steps when called:

  1. If number is not a Number, return false.
  2. If number is not finite, return false.
  3. Otherwise, return true.

21.1.2.3 Number.isInteger ( number )

This function performs the following steps when called:

  1. Return IsIntegralNumber(number).

21.1.2.4 Number.isNaN ( number )

This function performs the following steps when called:

  1. If number is not a Number, return false.
  2. If number is NaN, return true.
  3. Otherwise, return false.
Note

This function differs from the global isNaN function (19.2.3) in that it does not convert its argument to a Number before determining whether it is NaN.

21.1.2.5 Number.isSafeInteger ( number )

Note

An integer n is a "safe integer" if and only if the Number value for n is not the Number value for any other integer.

This function performs the following steps when called:

  1. If IsIntegralNumber(number) is true, then
    1. If abs((number)) ≤ 253 - 1, return true.
  2. Return false.

21.1.2.6 Number.MAX_SAFE_INTEGER

Note

Due to rounding behaviour necessitated by precision limitations of IEEE 754-2019, the Number value for every integer greater than Number.MAX_SAFE_INTEGER is shared with at least one other integer. Such large-magnitude integers are therefore not safe, and are not guaranteed to be exactly representable as Number values or even to be distinguishable from each other. For example, both 9007199254740992 and 9007199254740993 evaluate to the Number value 9007199254740992𝔽.

The value of Number.MAX_SAFE_INTEGER is 9007199254740991𝔽 (𝔽(253 - 1)).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.7 Number.MAX_VALUE

The value of Number.MAX_VALUE is the largest positive finite value of the Number type, which is approximately 1.7976931348623157 × 10308.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.8 Number.MIN_SAFE_INTEGER

Note

Due to rounding behaviour necessitated by precision limitations of IEEE 754-2019, the Number value for every integer less than Number.MIN_SAFE_INTEGER is shared with at least one other integer. Such large-magnitude integers are therefore not safe, and are not guaranteed to be exactly representable as Number values or even to be distinguishable from each other. For example, both -9007199254740992 and -9007199254740993 evaluate to the Number value -9007199254740992𝔽.

The value of Number.MIN_SAFE_INTEGER is -9007199254740991𝔽 (𝔽(-(253 - 1))).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.9 Number.MIN_VALUE

The value of Number.MIN_VALUE is the smallest positive value of the Number type, which is approximately 5 × 10-324.

In the IEEE 754-2019 double precision binary representation, the smallest possible value is a denormalized number. If an implementation does not support denormalized values, the value of Number.MIN_VALUE must be the smallest non-zero positive value that can actually be represented by the implementation.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.10 Number.NaN

The value of Number.NaN is NaN.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.11 Number.NEGATIVE_INFINITY

The value of Number.NEGATIVE_INFINITY is -∞𝔽.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.12 Number.parseFloat ( string )

The initial value of the "parseFloat" property is %parseFloat%.

21.1.2.13 Number.parseInt ( string, radix )

The initial value of the "parseInt" property is %parseInt%.

21.1.2.14 Number.POSITIVE_INFINITY

The value of Number.POSITIVE_INFINITY is +∞𝔽.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.15 Number.prototype

The initial value of Number.prototype is the Number prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.3 Properties of the Number Prototype Object

The Number prototype object:

  • is %Number.prototype%.
  • is an ordinary object.
  • is itself a Number object; it has a [[NumberData]] internal slot with the value +0𝔽.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.

Unless explicitly stated otherwise, the methods of the Number prototype object defined below are not generic and the this value passed to them must be either a Number value or an object that has a [[NumberData]] internal slot that has been initialized to a Number value.

The phrase “this Number value” within the specification of a method refers to the result returned by calling the abstract operation ThisNumberValue with the this value of the method invocation passed as the argument.

21.1.3.1 Number.prototype.constructor

The initial value of Number.prototype.constructor is %Number%.

21.1.3.2 Number.prototype.toExponential ( fractionDigits )

This method returns a String containing this Number value represented in decimal exponential notation with one digit before the significand's decimal point and fractionDigits digits after the significand's decimal point. If fractionDigits is undefined, it includes as many significand digits as necessary to uniquely specify the Number (just like in ToString except that in this case the Number is always output in exponential notation).

It performs the following steps when called:

  1. Let x be ? ThisNumberValue(this value).
  2. Let f be ? ToIntegerOrInfinity(fractionDigits).
  3. Assert: If fractionDigits is undefined, then f is 0.
  4. If x is not finite, return Number::toString(x, 10).
  5. If f < 0 or f > 100, throw a RangeError exception.
  6. Set x to (x).
  7. Let s be the empty String.
  8. If x < 0, then
    1. Set s to "-".
    2. Set x to -x.
  9. If x = 0, then
    1. Let m be the String value consisting of f + 1 occurrences of the code unit 0x0030 (DIGIT ZERO).
    2. Let e be 0.
  10. Else,
    1. If fractionDigits is not undefined, then
      1. Let e and n be integers such that 10fn < 10f + 1 and for which n × 10e - f - x is as close to zero as possible. If there are two such sets of e and n, pick the e and n for which n × 10e - f is larger.
    2. Else,
      1. Let e, n, and ff be integers such that ff ≥ 0, 10ffn < 10ff + 1, 𝔽(n × 10e - ff) is 𝔽(x), and ff is as small as possible. Note that the decimal representation of n has ff + 1 digits, n is not divisible by 10, and the least significant digit of n is not necessarily uniquely determined by these criteria.
      2. Set f to ff.
    3. Let m be the String value consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
  11. If f ≠ 0, then
    1. Let a be the first code unit of m.
    2. Let b be the other f code units of m.
    3. Set m to the string-concatenation of a, ".", and b.
  12. If e = 0, then
    1. Let c be "+".
    2. Let d be "0".
  13. Else,
    1. If e > 0, then
      1. Let c be "+".
    2. Else,
      1. Assert: e < 0.
      2. Let c be "-".
      3. Set e to -e.
    3. Let d be the String value consisting of the digits of the decimal representation of e (in order, with no leading zeroes).
  14. Set m to the string-concatenation of m, "e", c, and d.
  15. Return the string-concatenation of s and m.
Note

For implementations that provide more accurate conversions than required by the rules above, it is recommended that the following alternative version of step 10.b.i be used as a guideline:

  1. Let e, n, and f be integers such that f ≥ 0, 10fn < 10f + 1, 𝔽(n × 10e - f) is 𝔽(x), and f is as small as possible. If there are multiple possibilities for n, choose the value of n for which 𝔽(n × 10e - f) is closest in value to 𝔽(x). If there are two such possible values of n, choose the one that is even.

21.1.3.3 Number.prototype.toFixed ( fractionDigits )

Note 1

This method returns a String containing this Number value represented in decimal fixed-point notation with fractionDigits digits after the decimal point. If fractionDigits is undefined, 0 is assumed.

It performs the following steps when called:

  1. Let x be ? ThisNumberValue(this value).
  2. Let f be ? ToIntegerOrInfinity(fractionDigits).
  3. Assert: If fractionDigits is undefined, then f is 0.
  4. If f is not finite, throw a RangeError exception.
  5. If f < 0 or f > 100, throw a RangeError exception.
  6. If x is not finite, return Number::toString(x, 10).
  7. Set x to (x).
  8. Let s be the empty String.
  9. If x < 0, then
    1. Set s to "-".
    2. Set x to -x.
  10. If x ≥ 1021, then
    1. Let m be ! ToString(𝔽(x)).
  11. Else,
    1. Let n be an integer for which n / 10f - x is as close to zero as possible. If there are two such n, pick the larger n.
    2. If n = 0, let m be "0". Otherwise, let m be the String value consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
    3. If f ≠ 0, then
      1. Let k be the length of m.
      2. If kf, then
        1. Let z be the String value consisting of f + 1 - k occurrences of the code unit 0x0030 (DIGIT ZERO).
        2. Set m to the string-concatenation of z and m.
        3. Set k to f + 1.
      3. Let a be the first k - f code units of m.
      4. Let b be the other f code units of m.
      5. Set m to the string-concatenation of a, ".", and b.
  12. Return the string-concatenation of s and m.
Note 2

The output of toFixed may be more precise than toString for some values because toString only prints enough significant digits to distinguish the number from adjacent Number values. For example,

(1000000000000000128).toString() returns "1000000000000000100", while
(1000000000000000128).toFixed(0) returns "1000000000000000128".

21.1.3.4 Number.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method produces a String value that represents this Number value formatted according to the conventions of the host environment's current locale. This method is implementation-defined, and it is permissible, but not encouraged, for it to return the same thing as toString.

The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

21.1.3.5 Number.prototype.toPrecision ( precision )

This method returns a String containing this Number value represented either in decimal exponential notation with one digit before the significand's decimal point and precision - 1 digits after the significand's decimal point or in decimal fixed notation with precision significant digits. If precision is undefined, it calls ToString instead.

It performs the following steps when called:

  1. Let x be ? ThisNumberValue(this value).
  2. If precision is undefined, return ! ToString(x).
  3. Let p be ? ToIntegerOrInfinity(precision).
  4. If x is not finite, return Number::toString(x, 10).
  5. If p < 1 or p > 100, throw a RangeError exception.
  6. Set x to (x).
  7. Let s be the empty String.
  8. If x < 0, then
    1. Set s to the code unit 0x002D (HYPHEN-MINUS).
    2. Set x to -x.
  9. If x = 0, then
    1. Let m be the String value consisting of p occurrences of the code unit 0x0030 (DIGIT ZERO).
    2. Let e be 0.
  10. Else,
    1. Let e and n be integers such that 10p - 1n < 10p and for which n × 10e - p + 1 - x is as close to zero as possible. If there are two such sets of e and n, pick the e and n for which n × 10e - p + 1 is larger.
    2. Let m be the String value consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
    3. If e < -6 or ep, then
      1. Assert: e ≠ 0.
      2. If p ≠ 1, then
        1. Let a be the first code unit of m.
        2. Let b be the other p - 1 code units of m.
        3. Set m to the string-concatenation of a, ".", and b.
      3. If e > 0, then
        1. Let c be the code unit 0x002B (PLUS SIGN).
      4. Else,
        1. Assert: e < 0.
        2. Let c be the code unit 0x002D (HYPHEN-MINUS).
        3. Set e to -e.
      5. Let d be the String value consisting of the digits of the decimal representation of e (in order, with no leading zeroes).
      6. Return the string-concatenation of s, m, the code unit 0x0065 (LATIN SMALL LETTER E), c, and d.
  11. If e = p - 1, return the string-concatenation of s and m.
  12. If e ≥ 0, then
    1. Set m to the string-concatenation of the first e + 1 code units of m, the code unit 0x002E (FULL STOP), and the remaining p - (e + 1) code units of m.
  13. Else,
    1. Set m to the string-concatenation of the code unit 0x0030 (DIGIT ZERO), the code unit 0x002E (FULL STOP), -(e + 1) occurrences of the code unit 0x0030 (DIGIT ZERO), and the String m.
  14. Return the string-concatenation of s and m.

21.1.3.6 Number.prototype.toString ( [ radix ] )

Note

The optional radix should be an integral Number value in the inclusive interval from 2𝔽 to 36𝔽. If radix is undefined then 10𝔽 is used as the value of radix.

This method performs the following steps when called:

  1. Let x be ? ThisNumberValue(this value).
  2. If radix is undefined, let radixMV be 10.
  3. Else, let radixMV be ? ToIntegerOrInfinity(radix).
  4. If radixMV is not in the inclusive interval from 2 to 36, throw a RangeError exception.
  5. Return Number::toString(x, radixMV).

This method is not generic; it throws a TypeError exception if its this value is not a Number or a Number object. Therefore, it cannot be transferred to other kinds of objects for use as a method.

The "length" property of this method is 1𝔽.

21.1.3.7 Number.prototype.valueOf ( )

  1. Return ? ThisNumberValue(this value).

21.1.3.7.1 ThisNumberValue ( value )

The abstract operation ThisNumberValue takes argument value (an ECMAScript language value) and returns either a normal completion containing a Number or a throw completion. It performs the following steps when called:

  1. If value is a Number, return value.
  2. If value is an Object and value has a [[NumberData]] internal slot, then
    1. Let n be value.[[NumberData]].
    2. Assert: n is a Number.
    3. Return n.
  3. Throw a TypeError exception.

21.1.4 Properties of Number Instances

Number instances are ordinary objects that inherit properties from the Number prototype object. Number instances also have a [[NumberData]] internal slot. The [[NumberData]] internal slot is the Number value represented by this Number object.

21.2 BigInt Objects

21.2.1 The BigInt Constructor

The BigInt constructor:

  • is %BigInt%.
  • is the initial value of the "BigInt" property of the global object.
  • performs a type conversion when called as a function rather than as a constructor.
  • is not intended to be used with the new operator or to be subclassed. It may be used as the value of an extends clause of a class definition but a super call to the BigInt constructor will cause an exception.

21.2.1.1 BigInt ( value )

This function performs the following steps when called:

  1. If NewTarget is not undefined, throw a TypeError exception.
  2. Let prim be ? ToPrimitive(value, number).
  3. If prim is a Number, return ? NumberToBigInt(prim).
  4. Otherwise, return ? ToBigInt(prim).

21.2.1.1.1 NumberToBigInt ( number )

The abstract operation NumberToBigInt takes argument number (a Number) and returns either a normal completion containing a BigInt or a throw completion. It performs the following steps when called:

  1. If IsIntegralNumber(number) is false, throw a RangeError exception.
  2. Return ((number)).

21.2.2 Properties of the BigInt Constructor

The BigInt constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

21.2.2.1 BigInt.asIntN ( bits, bigint )

This function performs the following steps when called:

  1. Set bits to ? ToIndex(bits).
  2. Set bigint to ? ToBigInt(bigint).
  3. Let mod be (bigint) modulo 2bits.
  4. If mod ≥ 2bits - 1, return (mod - 2bits); otherwise, return (mod).

21.2.2.2 BigInt.asUintN ( bits, bigint )

This function performs the following steps when called:

  1. Set bits to ? ToIndex(bits).
  2. Set bigint to ? ToBigInt(bigint).
  3. Return ((bigint) modulo 2bits).

21.2.2.3 BigInt.prototype

The initial value of BigInt.prototype is the BigInt prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.2.3 Properties of the BigInt Prototype Object

The BigInt prototype object:

The phrase “this BigInt value” within the specification of a method refers to the result returned by calling the abstract operation ThisBigIntValue with the this value of the method invocation passed as the argument.

21.2.3.1 BigInt.prototype.constructor

The initial value of BigInt.prototype.constructor is %BigInt%.

21.2.3.2 BigInt.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method produces a String value that represents this BigInt value formatted according to the conventions of the host environment's current locale. This method is implementation-defined, and it is permissible, but not encouraged, for it to return the same thing as toString.

The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

21.2.3.3 BigInt.prototype.toString ( [ radix ] )

Note

The optional radix should be an integral Number value in the inclusive interval from 2𝔽 to 36𝔽. If radix is undefined then 10𝔽 is used as the value of radix.

This method performs the following steps when called:

  1. Let x be ? ThisBigIntValue(this value).
  2. If radix is undefined, let radixMV be 10.
  3. Else, let radixMV be ? ToIntegerOrInfinity(radix).
  4. If radixMV is not in the inclusive interval from 2 to 36, throw a RangeError exception.
  5. Return BigInt::toString(x, radixMV).

This method is not generic; it throws a TypeError exception if its this value is not a BigInt or a BigInt object. Therefore, it cannot be transferred to other kinds of objects for use as a method.

21.2.3.4 BigInt.prototype.valueOf ( )

  1. Return ? ThisBigIntValue(this value).

21.2.3.4.1 ThisBigIntValue ( value )

The abstract operation ThisBigIntValue takes argument value (an ECMAScript language value) and returns either a normal completion containing a BigInt or a throw completion. It performs the following steps when called:

  1. If value is a BigInt, return value.
  2. If value is an Object and value has a [[BigIntData]] internal slot, then
    1. Assert: value.[[BigIntData]] is a BigInt.
    2. Return value.[[BigIntData]].
  3. Throw a TypeError exception.

21.2.3.5 BigInt.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "BigInt".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

21.2.4 Properties of BigInt Instances

BigInt instances are ordinary objects that inherit properties from the BigInt prototype object. BigInt instances also have a [[BigIntData]] internal slot. The [[BigIntData]] internal slot is the BigInt value represented by this BigInt object.

21.3 The Math Object

The Math object:

  • is %Math%.
  • is the initial value of the "Math" property of the global object.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is not a function object.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • does not have a [[Call]] internal method; it cannot be invoked as a function.
Note

In this specification, the phrase “the Number value for x” has a technical meaning defined in 6.1.6.1.

21.3.1 Value Properties of the Math Object

21.3.1.1 Math.E

The Number value for e, the base of the natural logarithms, which is approximately 2.7182818284590452354.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.3.1.2 Math.LN10

The Number value for the natural logarithm of 10, which is approximately 2.302585092994046.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.3.1.3 Math.LN2

The Number value for the natural logarithm of 2, which is approximately 0.6931471805599453.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.3.1.4 Math.LOG10E

The Number value for the base-10 logarithm of e, the base of the natural logarithms; this value is approximately 0.4342944819032518.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

The value of Math.LOG10E is approximately the reciprocal of the value of Math.LN10.

21.3.1.5 Math.LOG2E

The Number value for the base-2 logarithm of e, the base of the natural logarithms; this value is approximately 1.4426950408889634.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

The value of Math.LOG2E is approximately the reciprocal of the value of Math.LN2.

21.3.1.6 Math.PI

The Number value for π, the ratio of the circumference of a circle to its diameter, which is approximately 3.1415926535897932.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.3.1.7 Math.SQRT1_2

The Number value for the square root of ½, which is approximately 0.7071067811865476.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

The value of Math.SQRT1_2 is approximately the reciprocal of the value of Math.SQRT2.

21.3.1.8 Math.SQRT2

The Number value for the square root of 2, which is approximately 1.4142135623730951.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.3.1.9 Math [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Math".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

21.3.2 Function Properties of the Math Object

Note

The behaviour of the functions acos, acosh, asin, asinh, atan, atanh, atan2, cbrt, cos, cosh, exp, expm1, hypot, log, log1p, log2, log10, pow, random, sin, sinh, sqrt, tan, and tanh is not precisely specified here except to require specific results for certain argument values that represent boundary cases of interest. For other argument values, these functions are intended to compute approximations to the results of familiar mathematical functions, but some latitude is allowed in the choice of approximation algorithms. The general intent is that an implementer should be able to use the same mathematical library for ECMAScript on a given hardware platform that is available to C programmers on that platform.

Although the choice of algorithms is left to the implementation, it is recommended (but not specified by this standard) that implementations use the approximation algorithms for IEEE 754-2019 arithmetic contained in fdlibm, the freely distributable mathematical library from Sun Microsystems (http://www.netlib.org/fdlibm).

21.3.2.1 Math.abs ( x )

This function returns the absolute value of x; the result has the same magnitude as x but has positive sign.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is NaN, return NaN.
  3. If n is -0𝔽, return +0𝔽.
  4. If n is -∞𝔽, return +∞𝔽.
  5. If n < -0𝔽, return -n.
  6. Return n.

21.3.2.2 Math.acos ( x )

This function returns the inverse cosine of x. The result is expressed in radians and is in the inclusive interval from +0𝔽 to 𝔽(π).

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is NaN, n > 1𝔽, or n < -1𝔽, return NaN.
  3. If n is 1𝔽, return +0𝔽.
  4. Return an implementation-approximated Number value representing the result of the inverse cosine of (n).

21.3.2.3 Math.acosh ( x )

This function returns the inverse hyperbolic cosine of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is either NaN or +∞𝔽, return n.
  3. If n is 1𝔽, return +0𝔽.
  4. If n < 1𝔽, return NaN.
  5. Return an implementation-approximated Number value representing the result of the inverse hyperbolic cosine of (n).

21.3.2.4 Math.asin ( x )

This function returns the inverse sine of x. The result is expressed in radians and is in the inclusive interval from 𝔽(-π / 2) to 𝔽(π / 2).

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n > 1𝔽 or n < -1𝔽, return NaN.
  4. Return an implementation-approximated Number value representing the result of the inverse sine of (n).

21.3.2.5 Math.asinh ( x )

This function returns the inverse hyperbolic sine of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. Return an implementation-approximated Number value representing the result of the inverse hyperbolic sine of (n).

21.3.2.6 Math.atan ( x )

This function returns the inverse tangent of x. The result is expressed in radians and is in the inclusive interval from 𝔽(-π / 2) to 𝔽(π / 2).

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n is +∞𝔽, return an implementation-approximated Number value representing π / 2.
  4. If n is -∞𝔽, return an implementation-approximated Number value representing -π / 2.
  5. Return an implementation-approximated Number value representing the result of the inverse tangent of (n).

21.3.2.7 Math.atanh ( x )

This function returns the inverse hyperbolic tangent of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n > 1𝔽 or n < -1𝔽, return NaN.
  4. If n is 1𝔽, return +∞𝔽.
  5. If n is -1𝔽, return -∞𝔽.
  6. Return an implementation-approximated Number value representing the result of the inverse hyperbolic tangent of (n).

21.3.2.8 Math.atan2 ( y, x )

This function returns the inverse tangent of the quotient y / x of the arguments y and x, where the signs of y and x are used to determine the quadrant of the result. Note that it is intentional and traditional for the two-argument inverse tangent function that the argument named y be first and the argument named x be second. The result is expressed in radians and is in the inclusive interval from -π to +π.

It performs the following steps when called:

  1. Let ny be ? ToNumber(y).
  2. Let nx be ? ToNumber(x).
  3. If ny is NaN or nx is NaN, return NaN.
  4. If ny is +∞𝔽, then
    1. If nx is +∞𝔽, return an implementation-approximated Number value representing π / 4.
    2. If nx is -∞𝔽, return an implementation-approximated Number value representing 3π / 4.
    3. Return an implementation-approximated Number value representing π / 2.
  5. If ny is -∞𝔽, then
    1. If nx is +∞𝔽, return an implementation-approximated Number value representing -π / 4.
    2. If nx is -∞𝔽, return an implementation-approximated Number value representing -3π / 4.
    3. Return an implementation-approximated Number value representing -π / 2.
  6. If ny is +0𝔽, then
    1. If nx > +0𝔽 or nx is +0𝔽, return +0𝔽.
    2. Return an implementation-approximated Number value representing π.
  7. If ny is -0𝔽, then
    1. If nx > +0𝔽 or nx is +0𝔽, return -0𝔽.
    2. Return an implementation-approximated Number value representing -π.
  8. Assert: ny is finite and is neither +0𝔽 nor -0𝔽.
  9. If ny > +0𝔽, then
    1. If nx is +∞𝔽, return +0𝔽.
    2. If nx is -∞𝔽, return an implementation-approximated Number value representing π.
    3. If nx is either +0𝔽 or -0𝔽, return an implementation-approximated Number value representing π / 2.
  10. If ny < -0𝔽, then
    1. If nx is +∞𝔽, return -0𝔽.
    2. If nx is -∞𝔽, return an implementation-approximated Number value representing -π.
    3. If nx is either +0𝔽 or -0𝔽, return an implementation-approximated Number value representing -π / 2.
  11. Assert: nx is finite and is neither +0𝔽 nor -0𝔽.
  12. Let r be the inverse tangent of abs((ny) / (nx)).
  13. If nx < -0𝔽, then
    1. If ny > +0𝔽, set r to π - r.
    2. Else, set r to -π + r.
  14. Else,
    1. If ny < -0𝔽, set r to -r.
  15. Return an implementation-approximated Number value representing r.

21.3.2.9 Math.cbrt ( x )

This function returns the cube root of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. Return an implementation-approximated Number value representing the result of the cube root of (n).

21.3.2.10 Math.ceil ( x )

This function returns the smallest (closest to -∞) integral Number value that is not less than x. If x is already an integral Number, the result is x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. If n < -0𝔽 and n > -1𝔽, return -0𝔽.
  4. If n is an integral Number, return n.
  5. Return the smallest (closest to -∞) integral Number value that is not less than n.
Note

The value of Math.ceil(x) is the same as the value of -Math.floor(-x).

21.3.2.11 Math.clz32 ( x )

This function performs the following steps when called:

  1. Let n be ? ToUint32(x).
  2. Let p be the number of leading zero bits in the unsigned 32-bit binary representation of n.
  3. Return 𝔽(p).
Note

If n is either +0𝔽 or -0𝔽, this method returns 32𝔽. If the most significant bit of the 32-bit binary encoding of n is 1, this method returns +0𝔽.

21.3.2.12 Math.cos ( x )

This function returns the cosine of x. The argument is expressed in radians.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite, return NaN.
  3. If n is either +0𝔽 or -0𝔽, return 1𝔽.
  4. Return an implementation-approximated Number value representing the result of the cosine of (n).

21.3.2.13 Math.cosh ( x )

This function returns the hyperbolic cosine of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is NaN, return NaN.
  3. If n is either +∞𝔽 or -∞𝔽, return +∞𝔽.
  4. If n is either +0𝔽 or -0𝔽, return 1𝔽.
  5. Return an implementation-approximated Number value representing the result of the hyperbolic cosine of (n).
Note

The value of Math.cosh(x) is the same as the value of (Math.exp(x) + Math.exp(-x)) / 2.

21.3.2.14 Math.exp ( x )

This function returns the exponential function of x (e raised to the power of x, where e is the base of the natural logarithms).

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is either NaN or +∞𝔽, return n.
  3. If n is either +0𝔽 or -0𝔽, return 1𝔽.
  4. If n is -∞𝔽, return +0𝔽.
  5. Return an implementation-approximated Number value representing the result of the exponential function of (n).

21.3.2.15 Math.expm1 ( x )

This function returns the result of subtracting 1 from the exponential function of x (e raised to the power of x, where e is the base of the natural logarithms). The result is computed in a way that is accurate even when the value of x is close to 0.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, -0𝔽, or +∞𝔽, return n.
  3. If n is -∞𝔽, return -1𝔽.
  4. Return an implementation-approximated Number value representing the result of subtracting 1 from the exponential function of (n).

21.3.2.16 Math.floor ( x )

This function returns the greatest (closest to +∞) integral Number value that is not greater than x. If x is already an integral Number, the result is x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. If n < 1𝔽 and n > +0𝔽, return +0𝔽.
  4. If n is an integral Number, return n.
  5. Return the greatest (closest to +∞) integral Number value that is not greater than n.
Note

The value of Math.floor(x) is the same as the value of -Math.ceil(-x).

21.3.2.17 Math.fround ( x )

This function performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is NaN, return NaN.
  3. If n is one of +0𝔽, -0𝔽, +∞𝔽, or -∞𝔽, return n.
  4. Let n32 be the result of converting n to IEEE 754-2019 binary32 format using roundTiesToEven mode.
  5. Let n64 be the result of converting n32 to IEEE 754-2019 binary64 format.
  6. Return the ECMAScript Number value corresponding to n64.

21.3.2.18 Math.hypot ( ...args )

Given zero or more arguments, this function returns the square root of the sum of squares of its arguments.

It performs the following steps when called:

  1. Let coerced be a new empty List.
  2. For each element arg of args, do
    1. Let n be ? ToNumber(arg).
    2. Append n to coerced.
  3. For each element number of coerced, do
    1. If number is either +∞𝔽 or -∞𝔽, return +∞𝔽.
  4. Let onlyZero be true.
  5. For each element number of coerced, do
    1. If number is NaN, return NaN.
    2. If number is neither +0𝔽 nor -0𝔽, set onlyZero to false.
  6. If onlyZero is true, return +0𝔽.
  7. Return an implementation-approximated Number value representing the square root of the sum of squares of the mathematical values of the elements of coerced.

The "length" property of this function is 2𝔽.

Note

Implementations should take care to avoid the loss of precision from overflows and underflows that are prone to occur in naive implementations when this function is called with two or more arguments.

21.3.2.19 Math.imul ( x, y )

This function performs the following steps when called:

  1. Let a be (? ToUint32(x)).
  2. Let b be (? ToUint32(y)).
  3. Let product be (a × b) modulo 232.
  4. If product ≥ 231, return 𝔽(product - 232); otherwise return 𝔽(product).

21.3.2.20 Math.log ( x )

This function returns the natural logarithm of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is either NaN or +∞𝔽, return n.
  3. If n is 1𝔽, return +0𝔽.
  4. If n is either +0𝔽 or -0𝔽, return -∞𝔽.
  5. If n < -0𝔽, return NaN.
  6. Return an implementation-approximated Number value representing the result of the natural logarithm of (n).

21.3.2.21 Math.log1p ( x )

This function returns the natural logarithm of 1 + x. The result is computed in a way that is accurate even when the value of x is close to zero.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, -0𝔽, or +∞𝔽, return n.
  3. If n is -1𝔽, return -∞𝔽.
  4. If n < -1𝔽, return NaN.
  5. Return an implementation-approximated Number value representing the result of the natural logarithm of 1 + (n).

21.3.2.22 Math.log10 ( x )

This function returns the base 10 logarithm of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is either NaN or +∞𝔽, return n.
  3. If n is 1𝔽, return +0𝔽.
  4. If n is either +0𝔽 or -0𝔽, return -∞𝔽.
  5. If n < -0𝔽, return NaN.
  6. Return an implementation-approximated Number value representing the result of the base 10 logarithm of (n).

21.3.2.23 Math.log2 ( x )

This function returns the base 2 logarithm of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is either NaN or +∞𝔽, return n.
  3. If n is 1𝔽, return +0𝔽.
  4. If n is either +0𝔽 or -0𝔽, return -∞𝔽.
  5. If n < -0𝔽, return NaN.
  6. Return an implementation-approximated Number value representing the result of the base 2 logarithm of (n).

21.3.2.24 Math.max ( ...args )

Given zero or more arguments, this function calls ToNumber on each of the arguments and returns the largest of the resulting values.

It performs the following steps when called:

  1. Let coerced be a new empty List.
  2. For each element arg of args, do
    1. Let n be ? ToNumber(arg).
    2. Append n to coerced.
  3. Let highest be -∞𝔽.
  4. For each element number of coerced, do
    1. If number is NaN, return NaN.
    2. If number is +0𝔽 and highest is -0𝔽, set highest to +0𝔽.
    3. If number > highest, set highest to number.
  5. Return highest.
Note

The comparison of values to determine the largest value is done using the IsLessThan algorithm except that +0𝔽 is considered to be larger than -0𝔽.

The "length" property of this function is 2𝔽.

21.3.2.25 Math.min ( ...args )

Given zero or more arguments, this function calls ToNumber on each of the arguments and returns the smallest of the resulting values.

It performs the following steps when called:

  1. Let coerced be a new empty List.
  2. For each element arg of args, do
    1. Let n be ? ToNumber(arg).
    2. Append n to coerced.
  3. Let lowest be +∞𝔽.
  4. For each element number of coerced, do
    1. If number is NaN, return NaN.
    2. If number is -0𝔽 and lowest is +0𝔽, set lowest to -0𝔽.
    3. If number < lowest, set lowest to number.
  5. Return lowest.
Note

The comparison of values to determine the largest value is done using the IsLessThan algorithm except that +0𝔽 is considered to be larger than -0𝔽.

The "length" property of this function is 2𝔽.

21.3.2.26 Math.pow ( base, exponent )

This function performs the following steps when called:

  1. Set base to ? ToNumber(base).
  2. Set exponent to ? ToNumber(exponent).
  3. Return Number::exponentiate(base, exponent).

21.3.2.27 Math.random ( )

This function returns a Number value with positive sign, greater than or equal to +0𝔽 but strictly less than 1𝔽, chosen randomly or pseudo randomly with approximately uniform distribution over that range, using an implementation-defined algorithm or strategy.

Each Math.random function created for distinct realms must produce a distinct sequence of values from successive calls.

21.3.2.28 Math.round ( x )

This function returns the Number value that is closest to x and is integral. If two integral Numbers are equally close to x, then the result is the Number value that is closer to +∞. If x is already integral, the result is x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is an integral Number, return n.
  3. If n < 0.5𝔽 and n > +0𝔽, return +0𝔽.
  4. If n < -0𝔽 and n-0.5𝔽, return -0𝔽.
  5. Return the integral Number closest to n, preferring the Number closer to +∞ in the case of a tie.
Note 1

Math.round(3.5) returns 4, but Math.round(-3.5) returns -3.

Note 2

The value of Math.round(x) is not always the same as the value of Math.floor(x + 0.5). When x is -0𝔽 or x is less than +0𝔽 but greater than or equal to -0.5𝔽, Math.round(x) returns -0𝔽, but Math.floor(x + 0.5) returns +0𝔽. Math.round(x) may also differ from the value of Math.floor(x + 0.5)because of internal rounding when computing x + 0.5.

21.3.2.29 Math.sign ( x )

This function returns the sign of x, indicating whether x is positive, negative, or zero.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n < -0𝔽, return -1𝔽.
  4. Return 1𝔽.

21.3.2.30 Math.sin ( x )

This function returns the sine of x. The argument is expressed in radians.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n is either +∞𝔽 or -∞𝔽, return NaN.
  4. Return an implementation-approximated Number value representing the result of the sine of (n).

21.3.2.31 Math.sinh ( x )

This function returns the hyperbolic sine of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. Return an implementation-approximated Number value representing the result of the hyperbolic sine of (n).
Note

The value of Math.sinh(x) is the same as the value of (Math.exp(x) - Math.exp(-x)) / 2.

21.3.2.32 Math.sqrt ( x )

This function returns the square root of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, -0𝔽, or +∞𝔽, return n.
  3. If n < -0𝔽, return NaN.
  4. Return an implementation-approximated Number value representing the result of the square root of (n).

21.3.2.33 Math.tan ( x )

This function returns the tangent of x. The argument is expressed in radians.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n is either +∞𝔽 or -∞𝔽, return NaN.
  4. Return an implementation-approximated Number value representing the result of the tangent of (n).

21.3.2.34 Math.tanh ( x )

This function returns the hyperbolic tangent of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n is +∞𝔽, return 1𝔽.
  4. If n is -∞𝔽, return -1𝔽.
  5. Return an implementation-approximated Number value representing the result of the hyperbolic tangent of (n).
Note

The value of Math.tanh(x) is the same as the value of (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x)).

21.3.2.35 Math.trunc ( x )

This function returns the integral part of the number x, removing any fractional digits. If x is already integral, the result is x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. If n < 1𝔽 and n > +0𝔽, return +0𝔽.
  4. If n < -0𝔽 and n > -1𝔽, return -0𝔽.
  5. Return the integral Number nearest n in the direction of +0𝔽.

21.4 Date Objects

21.4.1 Overview of Date Objects and Definitions of Abstract Operations

The following abstract operations operate on time values (defined in 21.4.1.1). Note that, in every case, if any argument to one of these functions is NaN, the result will be NaN.

21.4.1.1 Time Values and Time Range

Time measurement in ECMAScript is analogous to time measurement in POSIX, in particular sharing definition in terms of the proleptic Gregorian calendar, an epoch of midnight at the beginning of 1 January 1970 UTC, and an accounting of every day as comprising exactly 86,400 seconds (each of which is 1000 milliseconds long).

An ECMAScript time value is a Number, either a finite integral Number representing an instant in time to millisecond precision or NaN representing no specific instant. A time value that is a multiple of 24 × 60 × 60 × 1000 = 86,400,000 (i.e., is 86,400,000 × d for some integer d) represents the instant at the start of the UTC day that follows the epoch by d whole UTC days (preceding the epoch for negative d). Every other finite time value t is defined relative to the greatest preceding time value s that is such a multiple, and represents the instant that occurs within the same UTC day as s but follows it by (t - s) milliseconds.

Time values do not account for UTC leap seconds—there are no time values representing instants within positive leap seconds, and there are time values representing instants removed from the UTC timeline by negative leap seconds. However, the definition of time values nonetheless yields piecewise alignment with UTC, with discontinuities only at leap second boundaries and zero difference outside of leap seconds.

A Number can exactly represent all integers from -9,007,199,254,740,992 to 9,007,199,254,740,992 (21.1.2.8 and 21.1.2.6). A time value supports a slightly smaller range of -8,640,000,000,000,000 to 8,640,000,000,000,000 milliseconds. This yields a supported time value range of exactly -100,000,000 days to 100,000,000 days relative to midnight at the beginning of 1 January 1970 UTC.

The exact moment of midnight at the beginning of 1 January 1970 UTC is represented by the time value +0𝔽.

Note

In the proleptic Gregorian calendar, leap years are precisely those which are both divisible by 4 and either divisible by 400 or not divisible by 100.

The 400 year cycle of the proleptic Gregorian calendar contains 97 leap years. This yields an average of 365.2425 days per year, which is 31,556,952,000 milliseconds. Therefore, the maximum range a Number could represent exactly with millisecond precision is approximately -285,426 to 285,426 years relative to 1970. The smaller range supported by a time value as specified in this section is approximately -273,790 to 273,790 years relative to 1970.

21.4.1.2 Time-related Constants

These constants are referenced by algorithms in the following sections.

HoursPerDay = 24
MinutesPerHour = 60
SecondsPerMinute = 60
msPerSecond = 1000𝔽
msPerMinute = 60000𝔽 = msPerSecond × 𝔽(SecondsPerMinute)
msPerHour = 3600000𝔽 = msPerMinute × 𝔽(MinutesPerHour)
msPerDay = 86400000𝔽 = msPerHour × 𝔽(HoursPerDay)

21.4.1.3 Day ( t )

The abstract operation Day takes argument t (a finite time value) and returns an integral Number. It returns the day number of the day in which t falls. It performs the following steps when called:

  1. Return 𝔽(floor((t / msPerDay))).

21.4.1.4 TimeWithinDay ( t )

The abstract operation TimeWithinDay takes argument t (a finite time value) and returns an integral Number in the interval from +0𝔽 (inclusive) to msPerDay (exclusive). It returns the number of milliseconds since the start of the day in which t falls. It performs the following steps when called:

  1. Return 𝔽((t) modulo (msPerDay)).

21.4.1.5 DaysInYear ( y )

The abstract operation DaysInYear takes argument y (an integral Number) and returns 365𝔽 or 366𝔽. It returns the number of days in year y. Leap years have 366 days; all other years have 365. It performs the following steps when called:

  1. Let ry be (y).
  2. If (ry modulo 400) = 0, return 366𝔽.
  3. If (ry modulo 100) = 0, return 365𝔽.
  4. If (ry modulo 4) = 0, return 366𝔽.
  5. Return 365𝔽.

21.4.1.6 DayFromYear ( y )

The abstract operation DayFromYear takes argument y (an integral Number) and returns an integral Number. It returns the day number of the first day of year y. It performs the following steps when called:

  1. Let ry be (y).
  2. NOTE: In the following steps, numYears1, numYears4, numYears100, and numYears400 represent the number of years divisible by 1, 4, 100, and 400, respectively, that occur between the epoch and the start of year y. The number is negative if y is before the epoch.
  3. Let numYears1 be (ry - 1970).
  4. Let numYears4 be floor((ry - 1969) / 4).
  5. Let numYears100 be floor((ry - 1901) / 100).
  6. Let numYears400 be floor((ry - 1601) / 400).
  7. Return 𝔽(365 × numYears1 + numYears4 - numYears100 + numYears400).

21.4.1.7 TimeFromYear ( y )

The abstract operation TimeFromYear takes argument y (an integral Number) and returns a time value. It returns the time value of the start of year y. It performs the following steps when called:

  1. Return msPerDay × DayFromYear(y).

21.4.1.8 YearFromTime ( t )

The abstract operation YearFromTime takes argument t (a finite time value) and returns an integral Number. It returns the year in which t falls. It performs the following steps when called:

  1. Return the largest integral Number y (closest to +∞) such that TimeFromYear(y) ≤ t.

21.4.1.9 DayWithinYear ( t )

The abstract operation DayWithinYear takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 365𝔽. It performs the following steps when called:

  1. Return Day(t) - DayFromYear(YearFromTime(t)).

21.4.1.10 InLeapYear ( t )

The abstract operation InLeapYear takes argument t (a finite time value) and returns +0𝔽 or 1𝔽. It returns 1𝔽 if t is within a leap year and +0𝔽 otherwise. It performs the following steps when called:

  1. If DaysInYear(YearFromTime(t)) is 366𝔽, return 1𝔽; else return +0𝔽.

21.4.1.11 MonthFromTime ( t )

The abstract operation MonthFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 11𝔽. It returns a Number identifying the month in which t falls. A month value of +0𝔽 specifies January; 1𝔽 specifies February; 2𝔽 specifies March; 3𝔽 specifies April; 4𝔽 specifies May; 5𝔽 specifies June; 6𝔽 specifies July; 7𝔽 specifies August; 8𝔽 specifies September; 9𝔽 specifies October; 10𝔽 specifies November; and 11𝔽 specifies December. Note that MonthFromTime(+0𝔽) = +0𝔽, corresponding to Thursday, 1 January 1970. It performs the following steps when called:

  1. Let inLeapYear be InLeapYear(t).
  2. Let dayWithinYear be DayWithinYear(t).
  3. If dayWithinYear < 31𝔽, return +0𝔽.
  4. If dayWithinYear < 59𝔽 + inLeapYear, return 1𝔽.
  5. If dayWithinYear < 90𝔽 + inLeapYear, return 2𝔽.
  6. If dayWithinYear < 120𝔽 + inLeapYear, return 3𝔽.
  7. If dayWithinYear < 151𝔽 + inLeapYear, return 4𝔽.
  8. If dayWithinYear < 181𝔽 + inLeapYear, return 5𝔽.
  9. If dayWithinYear < 212𝔽 + inLeapYear, return 6𝔽.
  10. If dayWithinYear < 243𝔽 + inLeapYear, return 7𝔽.
  11. If dayWithinYear < 273𝔽 + inLeapYear, return 8𝔽.
  12. If dayWithinYear < 304𝔽 + inLeapYear, return 9𝔽.
  13. If dayWithinYear < 334𝔽 + inLeapYear, return 10𝔽.
  14. Assert: dayWithinYear < 365𝔽 + inLeapYear.
  15. Return 11𝔽.

21.4.1.12 DateFromTime ( t )

The abstract operation DateFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from 1𝔽 to 31𝔽. It returns the day of the month in which t falls. It performs the following steps when called:

  1. Let inLeapYear be InLeapYear(t).
  2. Let dayWithinYear be DayWithinYear(t).
  3. Let month be MonthFromTime(t).
  4. If month is +0𝔽, return dayWithinYear + 1𝔽.
  5. If month is 1𝔽, return dayWithinYear - 30𝔽.
  6. If month is 2𝔽, return dayWithinYear - 58𝔽 - inLeapYear.
  7. If month is 3𝔽, return dayWithinYear - 89𝔽 - inLeapYear.
  8. If month is 4𝔽, return dayWithinYear - 119𝔽 - inLeapYear.
  9. If month is 5𝔽, return dayWithinYear - 150𝔽 - inLeapYear.
  10. If month is 6𝔽, return dayWithinYear - 180𝔽 - inLeapYear.
  11. If month is 7𝔽, return dayWithinYear - 211𝔽 - inLeapYear.
  12. If month is 8𝔽, return dayWithinYear - 242𝔽 - inLeapYear.
  13. If month is 9𝔽, return dayWithinYear - 272𝔽 - inLeapYear.
  14. If month is 10𝔽, return dayWithinYear - 303𝔽 - inLeapYear.
  15. Assert: month is 11𝔽.
  16. Return dayWithinYear - 333𝔽 - inLeapYear.

21.4.1.13 WeekDay ( t )

The abstract operation WeekDay takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 6𝔽. It returns a Number identifying the day of the week in which t falls. A weekday value of +0𝔽 specifies Sunday; 1𝔽 specifies Monday; 2𝔽 specifies Tuesday; 3𝔽 specifies Wednesday; 4𝔽 specifies Thursday; 5𝔽 specifies Friday; and 6𝔽 specifies Saturday. Note that WeekDay(+0𝔽) = 4𝔽, corresponding to Thursday, 1 January 1970. It performs the following steps when called:

  1. Return 𝔽((Day(t) + 4𝔽) modulo 7).

21.4.1.14 HourFromTime ( t )

The abstract operation HourFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 23𝔽. It returns the hour of the day in which t falls. It performs the following steps when called:

  1. Return 𝔽(floor((t / msPerHour)) modulo HoursPerDay).

21.4.1.15 MinFromTime ( t )

The abstract operation MinFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 59𝔽. It returns the minute of the hour in which t falls. It performs the following steps when called:

  1. Return 𝔽(floor((t / msPerMinute)) modulo MinutesPerHour).

21.4.1.16 SecFromTime ( t )

The abstract operation SecFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 59𝔽. It returns the second of the minute in which t falls. It performs the following steps when called:

  1. Return 𝔽(floor((t / msPerSecond)) modulo SecondsPerMinute).

21.4.1.17 msFromTime ( t )

The abstract operation msFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 999𝔽. It returns the millisecond of the second in which t falls. It performs the following steps when called:

  1. Return 𝔽((t) modulo (msPerSecond)).

21.4.1.18 GetUTCEpochNanoseconds ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond )

The abstract operation GetUTCEpochNanoseconds takes arguments year (an integer), month (an integer in the inclusive interval from 1 to 12), day (an integer in the inclusive interval from 1 to 31), hour (an integer in the inclusive interval from 0 to 23), minute (an integer in the inclusive interval from 0 to 59), second (an integer in the inclusive interval from 0 to 59), millisecond (an integer in the inclusive interval from 0 to 999), microsecond (an integer in the inclusive interval from 0 to 999), and nanosecond (an integer in the inclusive interval from 0 to 999) and returns a BigInt. The returned value represents a number of nanoseconds since the epoch that corresponds to the given ISO 8601 calendar date and wall-clock time in UTC. It performs the following steps when called:

  1. Let date be MakeDay(𝔽(year), 𝔽(month - 1), 𝔽(day)).
  2. Let time be MakeTime(𝔽(hour), 𝔽(minute), 𝔽(second), 𝔽(millisecond)).
  3. Let ms be MakeDate(date, time).
  4. Assert: ms is an integral Number.
  5. Return ((ms) × 106 + microsecond × 103 + nanosecond).

21.4.1.19 Time Zone Identifiers

Time zones in ECMAScript are represented by time zone identifiers, which are Strings composed entirely of code units in the inclusive interval from 0x0000 to 0x007F. Time zones supported by an ECMAScript implementation may be available named time zones, represented by the [[Identifier]] field of the Time Zone Identifier Records returned by AvailableNamedTimeZoneIdentifiers, or offset time zones, represented by Strings for which IsTimeZoneOffsetString returns true.

A primary time zone identifier is the preferred identifier for an available named time zone. A non-primary time zone identifier is an identifier for an available named time zone that is not a primary time zone identifier. An available named time zone identifier is either a primary time zone identifier or a non-primary time zone identifier. Each available named time zone identifier is associated with exactly one available named time zone. Each available named time zone is associated with exactly one primary time zone identifier and zero or more non-primary time zone identifiers.

ECMAScript implementations must support an available named time zone with the identifier "UTC", which must be the primary time zone identifier for the UTC time zone. In addition, implementations may support any number of other available named time zones.

Implementations that follow the requirements for time zones as described in the ECMA-402 Internationalization API specification are called time zone aware. Time zone aware implementations must support available named time zones corresponding to the Zone and Link names of the IANA Time Zone Database, and only such names. In time zone aware implementations, a primary time zone identifier is a Zone name, and a non-primary time zone identifier is a Link name, respectively, in the IANA Time Zone Database except as specifically overridden by AvailableNamedTimeZoneIdentifiers as specified in the ECMA-402 specification. Implementations that do not support the entire IANA Time Zone Database are still recommended to use IANA Time Zone Database names as identifiers to represent time zones.

21.4.1.20 GetNamedTimeZoneEpochNanoseconds ( timeZoneIdentifier, year, month, day, hour, minute, second, millisecond, microsecond, nanosecond )

The implementation-defined abstract operation GetNamedTimeZoneEpochNanoseconds takes arguments timeZoneIdentifier (a String), year (an integer), month (an integer in the inclusive interval from 1 to 12), day (an integer in the inclusive interval from 1 to 31), hour (an integer in the inclusive interval from 0 to 23), minute (an integer in the inclusive interval from 0 to 59), second (an integer in the inclusive interval from 0 to 59), millisecond (an integer in the inclusive interval from 0 to 999), microsecond (an integer in the inclusive interval from 0 to 999), and nanosecond (an integer in the inclusive interval from 0 to 999) and returns a List of BigInts. Each value in the returned List represents a number of nanoseconds since the epoch that corresponds to the given ISO 8601 calendar date and wall-clock time in the named time zone identified by timeZoneIdentifier.

When the input represents a local time occurring more than once because of a negative time zone transition (e.g. when daylight saving time ends or the time zone offset is decreased due to a time zone rule change), the returned List will have more than one element and will be sorted by ascending numerical value. When the input represents a local time skipped because of a positive time zone transition (e.g. when daylight saving time begins or the time zone offset is increased due to a time zone rule change), the returned List will be empty. Otherwise, the returned List will have one element.

The default implementation of GetNamedTimeZoneEpochNanoseconds, to be used for ECMAScript implementations that do not include local political rules for any time zones, performs the following steps when called:

  1. Assert: timeZoneIdentifier is "UTC".
  2. Let epochNanoseconds be GetUTCEpochNanoseconds(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond).
  3. Return « epochNanoseconds ».
Note

It is required for time zone aware implementations (and recommended for all others) to use the time zone information of the IANA Time Zone Database https://www.iana.org/time-zones/.

1:30 AM on 5 November 2017 in America/New_York is repeated twice, so GetNamedTimeZoneEpochNanoseconds("America/New_York", 2017, 11, 5, 1, 30, 0, 0, 0, 0) would return a List of length 2 in which the first element represents 05:30 UTC (corresponding with 01:30 US Eastern Daylight Time at UTC offset -04:00) and the second element represents 06:30 UTC (corresponding with 01:30 US Eastern Standard Time at UTC offset -05:00).

2:30 AM on 12 March 2017 in America/New_York does not exist, so GetNamedTimeZoneEpochNanoseconds("America/New_York", 2017, 3, 12, 2, 30, 0, 0, 0, 0) would return an empty List.

21.4.1.21 GetNamedTimeZoneOffsetNanoseconds ( timeZoneIdentifier, epochNanoseconds )

The implementation-defined abstract operation GetNamedTimeZoneOffsetNanoseconds takes arguments timeZoneIdentifier (a String) and epochNanoseconds (a BigInt) and returns an integer.

The returned integer represents the offset from UTC of the named time zone identified by timeZoneIdentifier, at the instant corresponding with epochNanoseconds relative to the epoch, both in nanoseconds.

The default implementation of GetNamedTimeZoneOffsetNanoseconds, to be used for ECMAScript implementations that do not include local political rules for any time zones, performs the following steps when called:

  1. Assert: timeZoneIdentifier is "UTC".
  2. Return 0.
Note

Time zone offset values may be positive or negative.

21.4.1.22 Time Zone Identifier Record

A Time Zone Identifier Record is a Record used to describe an available named time zone identifier and its corresponding primary time zone identifier.

Time Zone Identifier Records have the fields listed in Table 61.

Table 61: Time Zone Identifier Record Fields
Field Name Value Meaning
[[Identifier]] a String An available named time zone identifier that is supported by the implementation.
[[PrimaryIdentifier]] a String The primary time zone identifier that [[Identifier]] resolves to.
Note

If [[Identifier]] is a primary time zone identifier, then [[Identifier]] is [[PrimaryIdentifier]].

21.4.1.23 AvailableNamedTimeZoneIdentifiers ( )

The implementation-defined abstract operation AvailableNamedTimeZoneIdentifiers takes no arguments and returns a List of Time Zone Identifier Records. Its result describes all available named time zone identifiers in this implementation, as well as the primary time zone identifier corresponding to each available named time zone identifier. The List is ordered according to the [[Identifier]] field of each Time Zone Identifier Record.

Time zone aware implementations, including all implementations that implement the ECMA-402 Internationalization API, must implement the AvailableNamedTimeZoneIdentifiers abstract operation as specified in the ECMA-402 specification. For implementations that are not time zone aware, AvailableNamedTimeZoneIdentifiers performs the following steps when called:

  1. If the implementation does not include local political rules for any time zones, then
    1. Return « the Time Zone Identifier Record { [[Identifier]]: "UTC", [[PrimaryIdentifier]]: "UTC" } ».
  2. Let identifiers be the List of unique available named time zone identifiers.
  3. Sort identifiers into the same order as if an Array of the same values had been sorted using %Array.prototype.sort% with undefined as comparefn.
  4. Let result be a new empty List.
  5. For each element identifier of identifiers, do
    1. Let primary be identifier.
    2. If identifier is a non-primary time zone identifier in this implementation and identifier is not "UTC", then
      1. Set primary to the primary time zone identifier associated with identifier.
      2. NOTE: An implementation may need to resolve identifier iteratively to obtain the primary time zone identifier.
    3. Let record be the Time Zone Identifier Record { [[Identifier]]: identifier, [[PrimaryIdentifier]]: primary }.
    4. Append record to result.
  6. Assert: result contains a Time Zone Identifier Record r such that r.[[Identifier]] is "UTC" and r.[[PrimaryIdentifier]] is "UTC".
  7. Return result.

21.4.1.24 SystemTimeZoneIdentifier ( )

The implementation-defined abstract operation SystemTimeZoneIdentifier takes no arguments and returns a String. It returns a String representing the host environment's current time zone, which is either a String representing a UTC offset for which IsTimeZoneOffsetString returns true, or a primary time zone identifier. It performs the following steps when called:

  1. If the implementation only supports the UTC time zone, return "UTC".
  2. Let systemTimeZoneString be the String representing the host environment's current time zone, either a primary time zone identifier or an offset time zone identifier.
  3. Return systemTimeZoneString.
Note

To ensure the level of functionality that implementations commonly provide in the methods of the Date object, it is recommended that SystemTimeZoneIdentifier return an IANA time zone name corresponding to the host environment's time zone setting, if such a thing exists. GetNamedTimeZoneEpochNanoseconds and GetNamedTimeZoneOffsetNanoseconds must reflect the local political rules for standard time and daylight saving time in that time zone, if such rules exist.

For example, if the host environment is a browser on a system where the user has chosen US Eastern Time as their time zone, SystemTimeZoneIdentifier returns "America/New_York".

21.4.1.25 LocalTime ( t )

The abstract operation LocalTime takes argument t (a finite time value) and returns an integral Number. It converts t from UTC to local time. The local political rules for standard time and daylight saving time in effect at t should be used to determine the result in the way specified in this section. It performs the following steps when called:

  1. Let systemTimeZoneIdentifier be SystemTimeZoneIdentifier().
  2. If IsTimeZoneOffsetString(systemTimeZoneIdentifier) is true, then
    1. Let offsetNs be ParseTimeZoneOffsetString(systemTimeZoneIdentifier).
  3. Else,
    1. Let offsetNs be GetNamedTimeZoneOffsetNanoseconds(systemTimeZoneIdentifier, ((t) × 106)).
  4. Let offsetMs be truncate(offsetNs / 106).
  5. Return t + 𝔽(offsetMs).
Note 1

If political rules for the local time t are not available within the implementation, the result is t because SystemTimeZoneIdentifier returns "UTC" and GetNamedTimeZoneOffsetNanoseconds returns 0.

Note 2

It is required for time zone aware implementations (and recommended for all others) to use the time zone information of the IANA Time Zone Database https://www.iana.org/time-zones/.

Note 3

Two different input time values tUTC are converted to the same local time tlocal at a negative time zone transition when there are repeated times (e.g. the daylight saving time ends or the time zone adjustment is decreased.).

LocalTime(UTC(tlocal)) is not necessarily always equal to tlocal. Correspondingly, UTC(LocalTime(tUTC)) is not necessarily always equal to tUTC.

21.4.1.26 UTC ( t )

The abstract operation UTC takes argument t (a Number) and returns a time value. It converts t from local time to a UTC time value. The local political rules for standard time and daylight saving time in effect at t should be used to determine the result in the way specified in this section. It performs the following steps when called:

  1. If t is not finite, return NaN.
  2. Let systemTimeZoneIdentifier be SystemTimeZoneIdentifier().
  3. If IsTimeZoneOffsetString(systemTimeZoneIdentifier) is true, then
    1. Let offsetNs be ParseTimeZoneOffsetString(systemTimeZoneIdentifier).
  4. Else,
    1. Let possibleInstants be GetNamedTimeZoneEpochNanoseconds(systemTimeZoneIdentifier, (YearFromTime(t)), (MonthFromTime(t)) + 1, (DateFromTime(t)), (HourFromTime(t)), (MinFromTime(t)), (SecFromTime(t)), (msFromTime(t)), 0, 0).
    2. NOTE: The following steps ensure that when t represents local time repeating multiple times at a negative time zone transition (e.g. when the daylight saving time ends or the time zone offset is decreased due to a time zone rule change) or skipped local time at a positive time zone transition (e.g. when the daylight saving time starts or the time zone offset is increased due to a time zone rule change), t is interpreted using the time zone offset before the transition.
    3. If possibleInstants is not empty, then
      1. Let disambiguatedInstant be possibleInstants[0].
    4. Else,
      1. NOTE: t represents a local time skipped at a positive time zone transition (e.g. due to daylight saving time starting or a time zone rule change increasing the UTC offset).
      2. Let possibleInstantsBefore be GetNamedTimeZoneEpochNanoseconds(systemTimeZoneIdentifier, (YearFromTime(tBefore)), (MonthFromTime(tBefore)) + 1, (DateFromTime(tBefore)), (HourFromTime(tBefore)), (MinFromTime(tBefore)), (SecFromTime(tBefore)), (msFromTime(tBefore)), 0, 0), where tBefore is the largest integral Number < t for which possibleInstantsBefore is not empty (i.e., tBefore represents the last local time before the transition).
      3. Let disambiguatedInstant be the last element of possibleInstantsBefore.
    5. Let offsetNs be GetNamedTimeZoneOffsetNanoseconds(systemTimeZoneIdentifier, disambiguatedInstant).
  5. Let offsetMs be truncate(offsetNs / 106).
  6. Return t - 𝔽(offsetMs).

Input t is nominally a time value but may be any Number value. The algorithm must not limit t to the time value range, so that inputs corresponding with a boundary of the time value range can be supported regardless of local UTC offset. For example, the maximum time value is 8.64 × 1015, corresponding with "+275760-09-13T00:00:00Z". In an environment where the local time zone offset is ahead of UTC by 1 hour at that instant, it is represented by the larger input of 8.64 × 1015 + 3.6 × 106, corresponding with "+275760-09-13T01:00:00+01:00".

If political rules for the local time t are not available within the implementation, the result is t because SystemTimeZoneIdentifier returns "UTC" and GetNamedTimeZoneOffsetNanoseconds returns 0.

Note 1

It is required for time zone aware implementations (and recommended for all others) to use the time zone information of the IANA Time Zone Database https://www.iana.org/time-zones/.

1:30 AM on 5 November 2017 in America/New_York is repeated twice (fall backward), but it must be interpreted as 1:30 AM UTC-04 instead of 1:30 AM UTC-05. In UTC(TimeClip(MakeDate(MakeDay(2017, 10, 5), MakeTime(1, 30, 0, 0)))), the value of offsetMs is -4 × msPerHour.

2:30 AM on 12 March 2017 in America/New_York does not exist, but it must be interpreted as 2:30 AM UTC-05 (equivalent to 3:30 AM UTC-04). In UTC(TimeClip(MakeDate(MakeDay(2017, 2, 12), MakeTime(2, 30, 0, 0)))), the value of offsetMs is -5 × msPerHour.

Note 2

UTC(LocalTime(tUTC)) is not necessarily always equal to tUTC. Correspondingly, LocalTime(UTC(tlocal)) is not necessarily always equal to tlocal.

21.4.1.27 MakeTime ( hour, min, sec, ms )

The abstract operation MakeTime takes arguments hour (a Number), min (a Number), sec (a Number), and ms (a Number) and returns a Number. It calculates a number of milliseconds. It performs the following steps when called:

  1. If hour is not finite, min is not finite, sec is not finite, or ms is not finite, return NaN.
  2. Let h be 𝔽(! ToIntegerOrInfinity(hour)).
  3. Let m be 𝔽(! ToIntegerOrInfinity(min)).
  4. Let s be 𝔽(! ToIntegerOrInfinity(sec)).
  5. Let milli be 𝔽(! ToIntegerOrInfinity(ms)).
  6. Return ((h × msPerHour + m × msPerMinute) + s × msPerSecond) + milli.
Note

The arithmetic in MakeTime is floating-point arithmetic, which is not associative, so the operations must be performed in the correct order.

21.4.1.28 MakeDay ( year, month, date )

The abstract operation MakeDay takes arguments year (a Number), month (a Number), and date (a Number) and returns a Number. It calculates a number of days. It performs the following steps when called:

  1. If year is not finite, month is not finite, or date is not finite, return NaN.
  2. Let y be 𝔽(! ToIntegerOrInfinity(year)).
  3. Let m be 𝔽(! ToIntegerOrInfinity(month)).
  4. Let dt be 𝔽(! ToIntegerOrInfinity(date)).
  5. Let ym be y + 𝔽(floor((m) / 12)).
  6. If ym is not finite, return NaN.
  7. Let mn be 𝔽((m) modulo 12).
  8. Find a finite time value t such that YearFromTime(t) is ym, MonthFromTime(t) is mn, and DateFromTime(t) is 1𝔽; but if this is not possible (because some argument is out of range), return NaN.
  9. Return Day(t) + dt - 1𝔽.

21.4.1.29 MakeDate ( day, time )

The abstract operation MakeDate takes arguments day (a Number) and time (a Number) and returns a Number. It calculates a number of milliseconds. It performs the following steps when called:

  1. If day is not finite or time is not finite, return NaN.
  2. Let tv be day × msPerDay + time.
  3. If tv is not finite, return NaN.
  4. Return tv.

21.4.1.30 MakeFullYear ( year )

The abstract operation MakeFullYear takes argument year (a Number) and returns an integral Number or NaN. It returns the full year associated with the integer part of year, interpreting any value in the inclusive interval from 0 to 99 as a count of years since the start of 1900. For alignment with the proleptic Gregorian calendar, "full year" is defined as the signed count of complete years since the start of year 0 (1 B.C.). It performs the following steps when called:

  1. If year is NaN, return NaN.
  2. Let truncated be ! ToIntegerOrInfinity(year).
  3. If truncated is in the inclusive interval from 0 to 99, return 1900𝔽 + 𝔽(truncated).
  4. Return 𝔽(truncated).

21.4.1.31 TimeClip ( time )

The abstract operation TimeClip takes argument time (a Number) and returns a Number. It calculates a number of milliseconds. It performs the following steps when called:

  1. If time is not finite, return NaN.
  2. If abs((time)) > 8.64 × 1015, return NaN.
  3. Return 𝔽(! ToIntegerOrInfinity(time)).

21.4.1.32 Date Time String Format

ECMAScript defines a string interchange format for date-times based upon a simplification of the ISO 8601 calendar date extended format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ

Where the elements are as follows:

YYYY is the year in the proleptic Gregorian calendar as four decimal digits from 0000 to 9999, or as an expanded year of "+" or "-" followed by six decimal digits.
- "-" (hyphen) appears literally twice in the string.
MM is the month of the year as two decimal digits from 01 (January) to 12 (December).
DD is the day of the month as two decimal digits from 01 to 31.
T "T" appears literally in the string, to indicate the beginning of the time element.
HH is the number of complete hours that have passed since midnight as two decimal digits from 00 to 24.
: ":" (colon) appears literally twice in the string.
mm is the number of complete minutes since the start of the hour as two decimal digits from 00 to 59.
ss is the number of complete seconds since the start of the minute as two decimal digits from 00 to 59.
. "." (dot) appears literally in the string.
sss is the number of complete milliseconds since the start of the second as three decimal digits.
Z is the UTC offset representation specified as "Z" (for UTC with no offset) or as either "+" or "-" followed by a time expression HH:mm (a subset of the time zone offset string format for indicating local time ahead of or behind UTC, respectively)

This format includes date-only forms:

YYYY
YYYY-MM
YYYY-MM-DD
        

It also includes “date-time” forms that consist of one of the above date-only forms immediately followed by one of the following time forms with an optional UTC offset representation appended:

THH:mm
THH:mm:ss
THH:mm:ss.sss
        

A string containing out-of-bounds or nonconforming elements is not a valid instance of this format.

Note 1

As every day both starts and ends with midnight, the two notations 00:00 and 24:00 are available to distinguish the two midnights that can be associated with one date. This means that the following two notations refer to exactly the same point in time: 1995-02-04T24:00 and 1995-02-05T00:00. This interpretation of the latter form as "end of a calendar day" is consistent with ISO 8601, even though that specification reserves it for describing time intervals and does not permit it within representations of single points in time.

Note 2

There exists no international standard that specifies abbreviations for civil time zones like CET, EST, etc. and sometimes the same abbreviation is even used for two very different time zones. For this reason, both ISO 8601 and this format specify numeric representations of time zone offsets.

21.4.1.32.1 Expanded Years

Covering the full time value range of approximately 273,790 years forward or backward from 1 January 1970 (21.4.1.1) requires representing years before 0 or after 9999. ISO 8601 permits expansion of the year representation, but only by mutual agreement of the partners in information interchange. In the simplified ECMAScript format, such an expanded year representation shall have 6 digits and is always prefixed with a + or - sign. The year 0 is considered positive and must be prefixed with a + sign. The representation of the year 0 as -000000 is invalid. Strings matching the Date Time String Format with expanded years representing instants in time outside the range of a time value are treated as unrecognizable by Date.parse and cause that function to return NaN without falling back to implementation-specific behaviour or heuristics.

Note

Examples of date-time values with expanded years:

-271821-04-20T00:00:00Z 271822 B.C.
-000001-01-01T00:00:00Z 2 B.C.
+000000-01-01T00:00:00Z 1 B.C.
+000001-01-01T00:00:00Z 1 A.D.
+001970-01-01T00:00:00Z 1970 A.D.
+002009-12-15T00:00:00Z 2009 A.D.
+275760-09-13T00:00:00Z 275760 A.D.

21.4.1.33 Time Zone Offset String Format

ECMAScript defines a string interchange format for UTC offsets, derived from ISO 8601. The format is described by the following grammar. The usage of Unicode code points in this grammar is listed in Table 62.

Table 62: Time Zone Offset String Code Points
Code Point Unicode Name Abbreviation
U+2212 MINUS SIGN <MINUS>

Syntax

UTCOffset ::: TemporalSign Hour TemporalSign Hour HourSubcomponents[+Extended] TemporalSign Hour HourSubcomponents[~Extended] TemporalSign ::: ASCIISign <MINUS> ASCIISign ::: one of + - Hour ::: 0 DecimalDigit 1 DecimalDigit 20 21 22 23 HourSubcomponents[Extended] ::: TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TemporalDecimalFractionopt TimeSeparator[Extended] ::: [+Extended] : [~Extended] [empty] MinuteSecond ::: 0 DecimalDigit 1 DecimalDigit 2 DecimalDigit 3 DecimalDigit 4 DecimalDigit 5 DecimalDigit TemporalDecimalFraction ::: TemporalDecimalSeparator DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator ::: one of . ,

21.4.1.33.1 IsTimeZoneOffsetString ( offsetString )

The abstract operation IsTimeZoneOffsetString takes argument offsetString (a String) and returns a Boolean. The return value indicates whether offsetString conforms to the grammar given by UTCOffset. It performs the following steps when called:

  1. Let parseResult be ParseText(StringToCodePoints(offsetString), UTCOffset).
  2. If parseResult is a List of errors, return false.
  3. Return true.

21.4.1.33.2 ParseTimeZoneOffsetString ( offsetString )

The abstract operation ParseTimeZoneOffsetString takes argument offsetString (a String) and returns an integer. The return value is the UTC offset, as a number of nanoseconds, that corresponds to the String offsetString. It performs the following steps when called:

  1. Let parseResult be ParseText(StringToCodePoints(offsetString), UTCOffset).
  2. Assert: parseResult is not a List of errors.
  3. Assert: parseResult contains a TemporalSign Parse Node.
  4. Let parsedSign be the source text matched by the TemporalSign Parse Node contained within parseResult.
  5. If parsedSign is the single code point U+002D (HYPHEN-MINUS) or U+2212 (MINUS SIGN), then
    1. Let sign be -1.
  6. Else,
    1. Let sign be 1.
  7. NOTE: Applications of StringToNumber below do not lose precision, since each of the parsed values is guaranteed to be a sufficiently short string of decimal digits.
  8. Assert: parseResult contains an Hour Parse Node.
  9. Let parsedHours be the source text matched by the Hour Parse Node contained within parseResult.
  10. Let hours be (StringToNumber(CodePointsToString(parsedHours))).
  11. If parseResult does not contain a MinuteSecond Parse Node, then
    1. Let minutes be 0.
  12. Else,
    1. Let parsedMinutes be the source text matched by the first MinuteSecond Parse Node contained within parseResult.
    2. Let minutes be (StringToNumber(CodePointsToString(parsedMinutes))).
  13. If parseResult does not contain two MinuteSecond Parse Nodes, then
    1. Let seconds be 0.
  14. Else,
    1. Let parsedSeconds be the source text matched by the second MinuteSecond Parse Node contained within parseResult.
    2. Let seconds be (StringToNumber(CodePointsToString(parsedSeconds))).
  15. If parseResult does not contain a TemporalDecimalFraction Parse Node, then
    1. Let nanoseconds be 0.
  16. Else,
    1. Let parsedFraction be the source text matched by the TemporalDecimalFraction Parse Node contained within parseResult.
    2. Let fraction be the string-concatenation of CodePointsToString(parsedFraction) and "000000000".
    3. Let nanosecondsString be the substring of fraction from 1 to 10.
    4. Let nanoseconds be (StringToNumber(nanosecondsString)).
  17. Return sign × (((hours × 60 + minutes) × 60 + seconds) × 109 + nanoseconds).

21.4.2 The Date Constructor

The Date constructor:

  • is %Date%.
  • is the initial value of the "Date" property of the global object.
  • creates and initializes a new Date when called as a constructor.
  • returns a String representing the current time (UTC) when called as a function rather than as a constructor.
  • is a function whose behaviour differs based upon the number and types of its arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Date behaviour must include a super call to the Date constructor to create and initialize the subclass instance with a [[DateValue]] internal slot.

21.4.2.1 Date ( ...values )

This function performs the following steps when called:

  1. If NewTarget is undefined, then
    1. Let now be the time value (UTC) identifying the current time.
    2. Return ToDateString(now).
  2. Let numberOfArgs be the number of elements in values.
  3. If numberOfArgs = 0, then
    1. Let dv be the time value (UTC) identifying the current time.
  4. Else if numberOfArgs = 1, then
    1. Let value be values[0].
    2. If value is an Object and value has a [[DateValue]] internal slot, then
      1. Let tv be value.[[DateValue]].
    3. Else,
      1. Let v be ? ToPrimitive(value).
      2. If v is a String, then
        1. Assert: The next step never returns an abrupt completion because v is a String.
        2. Let tv be the result of parsing v as a date, in exactly the same manner as for the parse method (21.4.3.2).
      3. Else,
        1. Let tv be ? ToNumber(v).
    4. Let dv be TimeClip(tv).
  5. Else,
    1. Assert: numberOfArgs ≥ 2.
    2. Let y be ? ToNumber(values[0]).
    3. Let m be ? ToNumber(values[1]).
    4. If numberOfArgs > 2, let dt be ? ToNumber(values[2]); else let dt be 1𝔽.
    5. If numberOfArgs > 3, let h be ? ToNumber(values[3]); else let h be +0𝔽.
    6. If numberOfArgs > 4, let min be ? ToNumber(values[4]); else let min be +0𝔽.
    7. If numberOfArgs > 5, let s be ? ToNumber(values[5]); else let s be +0𝔽.
    8. If numberOfArgs > 6, let milli be ? ToNumber(values[6]); else let milli be +0𝔽.
    9. Let yr be MakeFullYear(y).
    10. Let finalDate be MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)).
    11. Let dv be TimeClip(UTC(finalDate)).
  6. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Date.prototype%", « [[DateValue]] »).
  7. Set O.[[DateValue]] to dv.
  8. Return O.

21.4.3 Properties of the Date Constructor

The Date constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has a "length" property whose value is 7𝔽.
  • has the following properties:

21.4.3.1 Date.now ( )

This function returns the time value designating the UTC date and time of the occurrence of the call to it.

21.4.3.2 Date.parse ( string )

This function applies the ToString operator to its argument. If ToString results in an abrupt completion the Completion Record is immediately returned. Otherwise, this function interprets the resulting String as a date and time; it returns a Number, the UTC time value corresponding to the date and time. The String may be interpreted as a local time, a UTC time, or a time in some other time zone, depending on the contents of the String. The function first attempts to parse the String according to the format described in Date Time String Format (21.4.1.32), including expanded years. If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats. Strings that are unrecognizable or contain out-of-bounds format element values shall cause this function to return NaN.

If the String conforms to the Date Time String Format, substitute values take the place of absent format elements. When the MM or DD elements are absent, "01" is used. When the HH, mm, or ss elements are absent, "00" is used. When the sss element is absent, "000" is used. When the UTC offset representation is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.

If x is any Date whose milliseconds amount is zero within a particular implementation of ECMAScript, then all of the following expressions should produce the same numeric value in that implementation, if all the properties referenced have their initial values:

x.valueOf()
Date.parse(x.toString())
Date.parse(x.toUTCString())
Date.parse(x.toISOString())

However, the expression

Date.parse(x.toLocaleString())

is not required to produce the same Number value as the preceding three expressions and, in general, the value produced by this function is implementation-defined when given any String value that does not conform to the Date Time String Format (21.4.1.32) and that could not be produced in that implementation by the toString or toUTCString method.

21.4.3.3 Date.prototype

The initial value of Date.prototype is the Date prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.4.3.4 Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] )

This function performs the following steps when called:

  1. Let y be ? ToNumber(year).
  2. If month is present, let m be ? ToNumber(month); else let m be +0𝔽.
  3. If date is present, let dt be ? ToNumber(date); else let dt be 1𝔽.
  4. If hours is present, let h be ? ToNumber(hours); else let h be +0𝔽.
  5. If minutes is present, let min be ? ToNumber(minutes); else let min be +0𝔽.
  6. If seconds is present, let s be ? ToNumber(seconds); else let s be +0𝔽.
  7. If ms is present, let milli be ? ToNumber(ms); else let milli be +0𝔽.
  8. Let yr be MakeFullYear(y).
  9. Return TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))).

The "length" property of this function is 7𝔽.

Note

This function differs from the Date constructor in two ways: it returns a time value as a Number, rather than creating a Date, and it interprets the arguments in UTC rather than as local time.

21.4.4 Properties of the Date Prototype Object

The Date prototype object:

  • is %Date.prototype%.
  • is itself an ordinary object.
  • is not a Date instance and does not have a [[DateValue]] internal slot.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.

Unless explicitly defined otherwise, the methods of the Date prototype object defined below are not generic and the this value passed to them must be an object that has a [[DateValue]] internal slot that has been initialized to a time value.

21.4.4.1 Date.prototype.constructor

The initial value of Date.prototype.constructor is %Date%.

21.4.4.2 Date.prototype.getDate ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return DateFromTime(LocalTime(t)).

21.4.4.3 Date.prototype.getDay ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return WeekDay(LocalTime(t)).

21.4.4.4 Date.prototype.getFullYear ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return YearFromTime(LocalTime(t)).

21.4.4.5 Date.prototype.getHours ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return HourFromTime(LocalTime(t)).

21.4.4.6 Date.prototype.getMilliseconds ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return msFromTime(LocalTime(t)).

21.4.4.7 Date.prototype.getMinutes ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return MinFromTime(LocalTime(t)).

21.4.4.8 Date.prototype.getMonth ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return MonthFromTime(LocalTime(t)).

21.4.4.9 Date.prototype.getSeconds ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return SecFromTime(LocalTime(t)).

21.4.4.10 Date.prototype.getTime ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Return dateObject.[[DateValue]].

21.4.4.11 Date.prototype.getTimezoneOffset ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return (t - LocalTime(t)) / msPerMinute.

21.4.4.12 Date.prototype.getUTCDate ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return DateFromTime(t).

21.4.4.13 Date.prototype.getUTCDay ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return WeekDay(t).

21.4.4.14 Date.prototype.getUTCFullYear ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return YearFromTime(t).

21.4.4.15 Date.prototype.getUTCHours ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return HourFromTime(t).

21.4.4.16 Date.prototype.getUTCMilliseconds ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return msFromTime(t).

21.4.4.17 Date.prototype.getUTCMinutes ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return MinFromTime(t).

21.4.4.18 Date.prototype.getUTCMonth ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return MonthFromTime(t).

21.4.4.19 Date.prototype.getUTCSeconds ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return SecFromTime(t).

21.4.4.20 Date.prototype.setDate ( date )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let dt be ? ToNumber(date).
  5. If t is NaN, return NaN.
  6. Set t to LocalTime(t).
  7. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
  8. Let u be TimeClip(UTC(newDate)).
  9. Set dateObject.[[DateValue]] to u.
  10. Return u.

21.4.4.21 Date.prototype.setFullYear ( year [ , month [ , date ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let y be ? ToNumber(year).
  5. If t is NaN, set t to +0𝔽; otherwise, set t to LocalTime(t).
  6. If month is not present, let m be MonthFromTime(t); otherwise, let m be ? ToNumber(month).
  7. If date is not present, let dt be DateFromTime(t); otherwise, let dt be ? ToNumber(date).
  8. Let newDate be MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)).
  9. Let u be TimeClip(UTC(newDate)).
  10. Set dateObject.[[DateValue]] to u.
  11. Return u.

The "length" property of this method is 3𝔽.

Note

If month is not present, this method behaves as if month was present with the value getMonth(). If date is not present, it behaves as if date was present with the value getDate().

21.4.4.22 Date.prototype.setHours ( hour [ , min [ , sec [ , ms ] ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let h be ? ToNumber(hour).
  5. If min is present, let m be ? ToNumber(min).
  6. If sec is present, let s be ? ToNumber(sec).
  7. If ms is present, let milli be ? ToNumber(ms).
  8. If t is NaN, return NaN.
  9. Set t to LocalTime(t).
  10. If min is not present, let m be MinFromTime(t).
  11. If sec is not present, let s be SecFromTime(t).
  12. If ms is not present, let milli be msFromTime(t).
  13. Let date be MakeDate(Day(t), MakeTime(h, m, s, milli)).
  14. Let u be TimeClip(UTC(date)).
  15. Set dateObject.[[DateValue]] to u.
  16. Return u.

The "length" property of this method is 4𝔽.

Note

If min is not present, this method behaves as if min was present with the value getMinutes(). If sec is not present, it behaves as if sec was present with the value getSeconds(). If ms is not present, it behaves as if ms was present with the value getMilliseconds().

21.4.4.23 Date.prototype.setMilliseconds ( ms )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Set ms to ? ToNumber(ms).
  5. If t is NaN, return NaN.
  6. Set t to LocalTime(t).
  7. Let time be MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms).
  8. Let u be TimeClip(UTC(MakeDate(Day(t), time))).
  9. Set dateObject.[[DateValue]] to u.
  10. Return u.

21.4.4.24 Date.prototype.setMinutes ( min [ , sec [ , ms ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let m be ? ToNumber(min).
  5. If sec is present, let s be ? ToNumber(sec).
  6. If ms is present, let milli be ? ToNumber(ms).
  7. If t is NaN, return NaN.
  8. Set t to LocalTime(t).
  9. If sec is not present, let s be SecFromTime(t).
  10. If ms is not present, let milli be msFromTime(t).
  11. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli)).
  12. Let u be TimeClip(UTC(date)).
  13. Set dateObject.[[DateValue]] to u.
  14. Return u.

The "length" property of this method is 3𝔽.

Note

If sec is not present, this method behaves as if sec was present with the value getSeconds(). If ms is not present, this behaves as if ms was present with the value getMilliseconds().

21.4.4.25 Date.prototype.setMonth ( month [ , date ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let m be ? ToNumber(month).
  5. If date is present, let dt be ? ToNumber(date).
  6. If t is NaN, return NaN.
  7. Set t to LocalTime(t).
  8. If date is not present, let dt be DateFromTime(t).
  9. Let newDate be MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)).
  10. Let u be TimeClip(UTC(newDate)).
  11. Set dateObject.[[DateValue]] to u.
  12. Return u.

The "length" property of this method is 2𝔽.

Note

If date is not present, this method behaves as if date was present with the value getDate().

21.4.4.26 Date.prototype.setSeconds ( sec [ , ms ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let s be ? ToNumber(sec).
  5. If ms is present, let milli be ? ToNumber(ms).
  6. If t is NaN, return NaN.
  7. Set t to LocalTime(t).
  8. If ms is not present, let milli be msFromTime(t).
  9. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)).
  10. Let u be TimeClip(UTC(date)).
  11. Set dateObject.[[DateValue]] to u.
  12. Return u.

The "length" property of this method is 2𝔽.

Note

If ms is not present, this method behaves as if ms was present with the value getMilliseconds().

21.4.4.27 Date.prototype.setTime ( time )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be ? ToNumber(time).
  4. Let v be TimeClip(t).
  5. Set dateObject.[[DateValue]] to v.
  6. Return v.

21.4.4.28 Date.prototype.setUTCDate ( date )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let dt be ? ToNumber(date).
  5. If t is NaN, return NaN.
  6. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
  7. Let v be TimeClip(newDate).
  8. Set dateObject.[[DateValue]] to v.
  9. Return v.

21.4.4.29 Date.prototype.setUTCFullYear ( year [ , month [ , date ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, set t to +0𝔽.
  5. Let y be ? ToNumber(year).
  6. If month is not present, let m be MonthFromTime(t); otherwise, let m be ? ToNumber(month).
  7. If date is not present, let dt be DateFromTime(t); otherwise, let dt be ? ToNumber(date).
  8. Let newDate be MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)).
  9. Let v be TimeClip(newDate).
  10. Set dateObject.[[DateValue]] to v.
  11. Return v.

The "length" property of this method is 3𝔽.

Note

If month is not present, this method behaves as if month was present with the value getUTCMonth(). If date is not present, it behaves as if date was present with the value getUTCDate().

21.4.4.30 Date.prototype.setUTCHours ( hour [ , min [ , sec [ , ms ] ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let h be ? ToNumber(hour).
  5. If min is present, let m be ? ToNumber(min).
  6. If sec is present, let s be ? ToNumber(sec).
  7. If ms is present, let milli be ? ToNumber(ms).
  8. If t is NaN, return NaN.
  9. If min is not present, let m be MinFromTime(t).
  10. If sec is not present, let s be SecFromTime(t).
  11. If ms is not present, let milli be msFromTime(t).
  12. Let date be MakeDate(Day(t), MakeTime(h, m, s, milli)).
  13. Let v be TimeClip(date).
  14. Set dateObject.[[DateValue]] to v.
  15. Return v.

The "length" property of this method is 4𝔽.

Note

If min is not present, this method behaves as if min was present with the value getUTCMinutes(). If sec is not present, it behaves as if sec was present with the value getUTCSeconds(). If ms is not present, it behaves as if ms was present with the value getUTCMilliseconds().

21.4.4.31 Date.prototype.setUTCMilliseconds ( ms )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Set ms to ? ToNumber(ms).
  5. If t is NaN, return NaN.
  6. Let time be MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms).
  7. Let v be TimeClip(MakeDate(Day(t), time)).
  8. Set dateObject.[[DateValue]] to v.
  9. Return v.

21.4.4.32 Date.prototype.setUTCMinutes ( min [ , sec [ , ms ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let m be ? ToNumber(min).
  5. If sec is present, let s be ? ToNumber(sec).
  6. If ms is present, let milli be ? ToNumber(ms).
  7. If t is NaN, return NaN.
  8. If sec is not present, let s be SecFromTime(t).
  9. If ms is not present, let milli be msFromTime(t).
  10. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli)).
  11. Let v be TimeClip(date).
  12. Set dateObject.[[DateValue]] to v.
  13. Return v.

The "length" property of this method is 3𝔽.

Note

If sec is not present, this method behaves as if sec was present with the value getUTCSeconds(). If ms is not present, it behaves as if ms was present with the value return by getUTCMilliseconds().

21.4.4.33 Date.prototype.setUTCMonth ( month [ , date ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let m be ? ToNumber(month).
  5. If date is present, let dt be ? ToNumber(date).
  6. If t is NaN, return NaN.
  7. If date is not present, let dt be DateFromTime(t).
  8. Let newDate be MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)).
  9. Let v be TimeClip(newDate).
  10. Set dateObject.[[DateValue]] to v.
  11. Return v.

The "length" property of this method is 2𝔽.

Note

If date is not present, this method behaves as if date was present with the value getUTCDate().

21.4.4.34 Date.prototype.setUTCSeconds ( sec [ , ms ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let s be ? ToNumber(sec).
  5. If ms is present, let milli be ? ToNumber(ms).
  6. If t is NaN, return NaN.
  7. If ms is not present, let milli be msFromTime(t).
  8. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)).
  9. Let v be TimeClip(date).
  10. Set dateObject.[[DateValue]] to v.
  11. Return v.

The "length" property of this method is 2𝔽.

Note

If ms is not present, this method behaves as if ms was present with the value getUTCMilliseconds().

21.4.4.35 Date.prototype.toDateString ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let tv be dateObject.[[DateValue]].
  4. If tv is NaN, return "Invalid Date".
  5. Let t be LocalTime(tv).
  6. Return DateString(t).

21.4.4.36 Date.prototype.toISOString ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let tv be dateObject.[[DateValue]].
  4. If tv is not finite, throw a RangeError exception.
  5. If tv corresponds with a year that cannot be represented in the Date Time String Format, throw a RangeError exception.
  6. Return a String representation of tv in the Date Time String Format on the UTC time scale, including all format elements and the UTC offset representation "Z".

21.4.4.37 Date.prototype.toJSON ( key )

This method provides a String representation of a Date for use by JSON.stringify (25.5.2).

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let tv be ? ToPrimitive(O, number).
  3. If tv is a Number and tv is not finite, return null.
  4. Return ? Invoke(O, "toISOString").
Note 1

The argument is ignored.

Note 2

This method is intentionally generic; it does not require that its this value be a Date. Therefore, it can be transferred to other kinds of objects for use as a method. However, it does require that any such object have a toISOString method.

21.4.4.38 Date.prototype.toLocaleDateString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method returns a String value. The contents of the String are implementation-defined, but are intended to represent the “date” portion of the Date in the current time zone in a convenient, human-readable form that corresponds to the conventions of the host environment's current locale.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

21.4.4.39 Date.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method returns a String value. The contents of the String are implementation-defined, but are intended to represent the Date in the current time zone in a convenient, human-readable form that corresponds to the conventions of the host environment's current locale.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

21.4.4.40 Date.prototype.toLocaleTimeString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method returns a String value. The contents of the String are implementation-defined, but are intended to represent the “time” portion of the Date in the current time zone in a convenient, human-readable form that corresponds to the conventions of the host environment's current locale.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

21.4.4.41 Date.prototype.toString ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let tv be dateObject.[[DateValue]].
  4. Return ToDateString(tv).
Note 1

For any Date d such that d.[[DateValue]] is evenly divisible by 1000, the result of Date.parse(d.toString()) = d.valueOf(). See 21.4.3.2.

Note 2

This method is not generic; it throws a TypeError exception if its this value is not a Date. Therefore, it cannot be transferred to other kinds of objects for use as a method.

21.4.4.41.1 TimeString ( tv )

The abstract operation TimeString takes argument tv (a Number, but not NaN) and returns a String. It performs the following steps when called:

  1. Let hour be ToZeroPaddedDecimalString((HourFromTime(tv)), 2).
  2. Let minute be ToZeroPaddedDecimalString((MinFromTime(tv)), 2).
  3. Let second be ToZeroPaddedDecimalString((SecFromTime(tv)), 2).
  4. Return the string-concatenation of hour, ":", minute, ":", second, the code unit 0x0020 (SPACE), and "GMT".

21.4.4.41.2 DateString ( tv )

The abstract operation DateString takes argument tv (a Number, but not NaN) and returns a String. It performs the following steps when called:

  1. Let weekday be the Name of the entry in Table 63 with the Number WeekDay(tv).
  2. Let month be the Name of the entry in Table 64 with the Number MonthFromTime(tv).
  3. Let day be ToZeroPaddedDecimalString((DateFromTime(tv)), 2).
  4. Let yv be YearFromTime(tv).
  5. If yv is +0𝔽 or yv > +0𝔽, let yearSign be the empty String; otherwise, let yearSign be "-".
  6. Let paddedYear be ToZeroPaddedDecimalString(abs((yv)), 4).
  7. Return the string-concatenation of weekday, the code unit 0x0020 (SPACE), month, the code unit 0x0020 (SPACE), day, the code unit 0x0020 (SPACE), yearSign, and paddedYear.
Table 63: Names of days of the week
Number Name
+0𝔽 "Sun"
1𝔽 "Mon"
2𝔽 "Tue"
3𝔽 "Wed"
4𝔽 "Thu"
5𝔽 "Fri"
6𝔽 "Sat"
Table 64: Names of months of the year
Number Name
+0𝔽 "Jan"
1𝔽 "Feb"
2𝔽 "Mar"
3𝔽 "Apr"
4𝔽 "May"
5𝔽 "Jun"
6𝔽 "Jul"
7𝔽 "Aug"
8𝔽 "Sep"
9𝔽 "Oct"
10𝔽 "Nov"
11𝔽 "Dec"

21.4.4.41.3 TimeZoneString ( tv )

The abstract operation TimeZoneString takes argument tv (an integral Number) and returns a String. It performs the following steps when called:

  1. Let systemTimeZoneIdentifier be SystemTimeZoneIdentifier().
  2. If IsTimeZoneOffsetString(systemTimeZoneIdentifier) is true, then
    1. Let offsetNs be ParseTimeZoneOffsetString(systemTimeZoneIdentifier).
  3. Else,
    1. Let offsetNs be GetNamedTimeZoneOffsetNanoseconds(systemTimeZoneIdentifier, ((tv) × 106)).
  4. Let offset be 𝔽(truncate(offsetNs / 106)).
  5. If offset is +0𝔽 or offset > +0𝔽, then
    1. Let offsetSign be "+".
    2. Let absOffset be offset.
  6. Else,
    1. Let offsetSign be "-".
    2. Let absOffset be -offset.
  7. Let offsetMin be ToZeroPaddedDecimalString((MinFromTime(absOffset)), 2).
  8. Let offsetHour be ToZeroPaddedDecimalString((HourFromTime(absOffset)), 2).
  9. Let tzName be an implementation-defined string that is either the empty String or the string-concatenation of the code unit 0x0020 (SPACE), the code unit 0x0028 (LEFT PARENTHESIS), an implementation-defined timezone name, and the code unit 0x0029 (RIGHT PARENTHESIS).
  10. Return the string-concatenation of offsetSign, offsetHour, offsetMin, and tzName.

21.4.4.41.4 ToDateString ( tv )

The abstract operation ToDateString takes argument tv (an integral Number or NaN) and returns a String. It performs the following steps when called:

  1. If tv is NaN, return "Invalid Date".
  2. Let t be LocalTime(tv).
  3. Return the string-concatenation of DateString(t), the code unit 0x0020 (SPACE), TimeString(t), and TimeZoneString(tv).

21.4.4.42 Date.prototype.toTimeString ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let tv be dateObject.[[DateValue]].
  4. If tv is NaN, return "Invalid Date".
  5. Let t be LocalTime(tv).
  6. Return the string-concatenation of TimeString(t) and TimeZoneString(tv).

21.4.4.43 Date.prototype.toUTCString ( )

This method returns a String value representing the instant in time corresponding to the this value. The format of the String is based upon "HTTP-date" from RFC 7231, generalized to support the full range of times supported by ECMAScript Dates.

It performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let tv be dateObject.[[DateValue]].
  4. If tv is NaN, return "Invalid Date".
  5. Let weekday be the Name of the entry in Table 63 with the Number WeekDay(tv).
  6. Let month be the Name of the entry in Table 64 with the Number MonthFromTime(tv).
  7. Let day be ToZeroPaddedDecimalString((DateFromTime(tv)), 2).
  8. Let yv be YearFromTime(tv).
  9. If yv is +0𝔽 or yv > +0𝔽, let yearSign be the empty String; otherwise, let yearSign be "-".
  10. Let paddedYear be ToZeroPaddedDecimalString(abs((yv)), 4).
  11. Return the string-concatenation of weekday, ",", the code unit 0x0020 (SPACE), day, the code unit 0x0020 (SPACE), month, the code unit 0x0020 (SPACE), yearSign, paddedYear, the code unit 0x0020 (SPACE), and TimeString(tv).

21.4.4.44 Date.prototype.valueOf ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Return dateObject.[[DateValue]].

21.4.4.45 Date.prototype [ @@toPrimitive ] ( hint )

This method is called by ECMAScript language operators to convert a Date to a primitive value. The allowed values for hint are "default", "number", and "string". Dates are unique among built-in ECMAScript object in that they treat "default" as being equivalent to "string", All other built-in ECMAScript objects treat "default" as being equivalent to "number".

It performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. If hint is either "string" or "default", then
    1. Let tryFirst be string.
  4. Else if hint is "number", then
    1. Let tryFirst be number.
  5. Else,
    1. Throw a TypeError exception.
  6. Return ? OrdinaryToPrimitive(O, tryFirst).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

The value of the "name" property of this method is "[Symbol.toPrimitive]".

21.4.5 Properties of Date Instances

Date instances are ordinary objects that inherit properties from the Date prototype object. Date instances also have a [[DateValue]] internal slot. The [[DateValue]] internal slot is the time value represented by this Date.

22 Text Processing

22.1 String Objects

22.1.1 The String Constructor

The String constructor:

  • is %String%.
  • is the initial value of the "String" property of the global object.
  • creates and initializes a new String object when called as a constructor.
  • performs a type conversion when called as a function rather than as a constructor.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified String behaviour must include a super call to the String constructor to create and initialize the subclass instance with a [[StringData]] internal slot.

22.1.1.1 String ( value )

This function performs the following steps when called:

  1. If value is not present, then
    1. Let s be the empty String.
  2. Else,
    1. If NewTarget is undefined and value is a Symbol, return SymbolDescriptiveString(value).
    2. Let s be ? ToString(value).
  3. If NewTarget is undefined, return s.
  4. Return StringCreate(s, ? GetPrototypeFromConstructor(NewTarget, "%String.prototype%")).

22.1.2 Properties of the String Constructor

The String constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

22.1.2.1 String.fromCharCode ( ...codeUnits )

This function may be called with any number of arguments which form the rest parameter codeUnits.

It performs the following steps when called:

  1. Let result be the empty String.
  2. For each element next of codeUnits, do
    1. Let nextCU be the code unit whose numeric value is (? ToUint16(next)).
    2. Set result to the string-concatenation of result and nextCU.
  3. Return result.

The "length" property of this function is 1𝔽.

22.1.2.2 String.fromCodePoint ( ...codePoints )

This function may be called with any number of arguments which form the rest parameter codePoints.

It performs the following steps when called:

  1. Let result be the empty String.
  2. For each element next of codePoints, do
    1. Let nextCP be ? ToNumber(next).
    2. If IsIntegralNumber(nextCP) is false, throw a RangeError exception.
    3. If (nextCP) < 0 or (nextCP) > 0x10FFFF, throw a RangeError exception.
    4. Set result to the string-concatenation of result and UTF16EncodeCodePoint((nextCP)).
  3. Assert: If codePoints is empty, then result is the empty String.
  4. Return result.

The "length" property of this function is 1𝔽.

22.1.2.3 String.prototype

The initial value of String.prototype is the String prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

22.1.2.4 String.raw ( template, ...substitutions )

This function may be called with a variable number of arguments. The first argument is template and the remainder of the arguments form the List substitutions.

It performs the following steps when called:

  1. Let substitutionCount be the number of elements in substitutions.
  2. Let cooked be ? ToObject(template).
  3. Let literals be ? ToObject(? Get(cooked, "raw")).
  4. Let literalCount be ? LengthOfArrayLike(literals).
  5. If literalCount ≤ 0, return the empty String.
  6. Let R be the empty String.
  7. Let nextIndex be 0.
  8. Repeat,
    1. Let nextLiteralVal be ? Get(literals, ! ToString(𝔽(nextIndex))).
    2. Let nextLiteral be ? ToString(nextLiteralVal).
    3. Set R to the string-concatenation of R and nextLiteral.
    4. If nextIndex + 1 = literalCount, return R.
    5. If nextIndex < substitutionCount, then
      1. Let nextSubVal be substitutions[nextIndex].
      2. Let nextSub be ? ToString(nextSubVal).
      3. Set R to the string-concatenation of R and nextSub.
    6. Set nextIndex to nextIndex + 1.
Note

This function is intended for use as a tag function of a Tagged Template (13.3.11). When called as such, the first argument will be a well formed template object and the rest parameter will contain the substitution values.

22.1.3 Properties of the String Prototype Object

The String prototype object:

  • is %String.prototype%.
  • is a String exotic object and has the internal methods specified for such objects.
  • has a [[StringData]] internal slot whose value is the empty String.
  • has a "length" property whose initial value is +0𝔽 and whose attributes are { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.

Unless explicitly stated otherwise, the methods of the String prototype object defined below are not generic and the this value passed to them must be either a String value or an object that has a [[StringData]] internal slot that has been initialized to a String value.

22.1.3.1 String.prototype.at ( index )

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let len be the length of S.
  4. Let relativeIndex be ? ToIntegerOrInfinity(index).
  5. If relativeIndex ≥ 0, then
    1. Let k be relativeIndex.
  6. Else,
    1. Let k be len + relativeIndex.
  7. If k < 0 or klen, return undefined.
  8. Return the substring of S from k to k + 1.

22.1.3.2 String.prototype.charAt ( pos )

Note 1

This method returns a single element String containing the code unit at index pos within the String value resulting from converting this object to a String. If there is no element at that index, the result is the empty String. The result is a String value, not a String object.

If pos is an integral Number, then the result of x.charAt(pos) is equivalent to the result of x.substring(pos, pos + 1).

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let position be ? ToIntegerOrInfinity(pos).
  4. Let size be the length of S.
  5. If position < 0 or positionsize, return the empty String.
  6. Return the substring of S from position to position + 1.
Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.3 String.prototype.charCodeAt ( pos )

Note 1

This method returns a Number (a non-negative integral Number less than 216) that is the numeric value of the code unit at index pos within the String resulting from converting this object to a String. If there is no element at that index, the result is NaN.

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let position be ? ToIntegerOrInfinity(pos).
  4. Let size be the length of S.
  5. If position < 0 or positionsize, return NaN.
  6. Return the Number value for the numeric value of the code unit at index position within the String S.
Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.4 String.prototype.codePointAt ( pos )

Note 1

This method returns a non-negative integral Number less than or equal to 0x10FFFF𝔽 that is the numeric value of the UTF-16 encoded code point (6.1.4) starting at the string element at index pos within the String resulting from converting this object to a String. If there is no element at that index, the result is undefined. If a valid UTF-16 surrogate pair does not begin at pos, the result is the code unit at pos.

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let position be ? ToIntegerOrInfinity(pos).
  4. Let size be the length of S.
  5. If position < 0 or positionsize, return undefined.
  6. Let cp be CodePointAt(S, position).
  7. Return 𝔽(cp.[[CodePoint]]).
Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.5 String.prototype.concat ( ...args )

Note 1

When this method is called it returns the String value consisting of the code units of the this value (converted to a String) followed by the code units of each of the arguments converted to a String. The result is a String value, not a String object.

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let R be S.
  4. For each element next of args, do
    1. Let nextString be ? ToString(next).
    2. Set R to the string-concatenation of R and nextString.
  5. Return R.

The "length" property of this method is 1𝔽.

Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.6 String.prototype.constructor

The initial value of String.prototype.constructor is %String%.

22.1.3.7 String.prototype.endsWith ( searchString [ , endPosition ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let isRegExp be ? IsRegExp(searchString).
  4. If isRegExp is true, throw a TypeError exception.
  5. Let searchStr be ? ToString(searchString).
  6. Let len be the length of S.
  7. If endPosition is undefined, let pos be len; else let pos be ? ToIntegerOrInfinity(endPosition).
  8. Let end be the result of clamping pos between 0 and len.
  9. Let searchLength be the length of searchStr.
  10. If searchLength = 0, return true.
  11. Let start be end - searchLength.
  12. If start < 0, return false.
  13. Let substring be the substring of S from start to end.
  14. If substring is searchStr, return true.
  15. Return false.
Note 1

This method returns true if the sequence of code units of searchString converted to a String is the same as the corresponding code units of this object (converted to a String) starting at endPosition - length(this). Otherwise it returns false.

Note 2

Throwing an exception if the first argument is a RegExp is specified in order to allow future editions to define extensions that allow such argument values.

Note 3

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.8 String.prototype.includes ( searchString [ , position ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let isRegExp be ? IsRegExp(searchString).
  4. If isRegExp is true, throw a TypeError exception.
  5. Let searchStr be ? ToString(searchString).
  6. Let pos be ? ToIntegerOrInfinity(position).
  7. Assert: If position is undefined, then pos is 0.
  8. Let len be the length of S.
  9. Let start be the result of clamping pos between 0 and len.
  10. Let index be StringIndexOf(S, searchStr, start).
  11. If index ≠ -1, return true.
  12. Return false.
Note 1

If searchString appears as a substring of the result of converting this object to a String, at one or more indices that are greater than or equal to position, this function returns true; otherwise, it returns false. If position is undefined, 0 is assumed, so as to search all of the String.

Note 2

Throwing an exception if the first argument is a RegExp is specified in order to allow future editions to define extensions that allow such argument values.

Note 3

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.9 String.prototype.indexOf ( searchString [ , position ] )

Note 1

If searchString appears as a substring of the result of converting this object to a String, at one or more indices that are greater than or equal to position, then the smallest such index is returned; otherwise, -1𝔽 is returned. If position is undefined, +0𝔽 is assumed, so as to search all of the String.

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let searchStr be ? ToString(searchString).
  4. Let pos be ? ToIntegerOrInfinity(position).
  5. Assert: If position is undefined, then pos is 0.
  6. Let len be the length of S.
  7. Let start be the result of clamping pos between 0 and len.
  8. Return 𝔽(StringIndexOf(S, searchStr, start)).
Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.10 String.prototype.isWellFormed ( )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Return IsStringWellFormedUnicode(S).

22.1.3.11 String.prototype.lastIndexOf ( searchString [ , position ] )

Note 1

If searchString appears as a substring of the result of converting this object to a String at one or more indices that are smaller than or equal to position, then the greatest such index is returned; otherwise, -1𝔽 is returned. If position is undefined, the length of the String value is assumed, so as to search all of the String.

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let searchStr be ? ToString(searchString).
  4. Let numPos be ? ToNumber(position).
  5. Assert: If position is undefined, then numPos is NaN.
  6. If numPos is NaN, let pos be +∞; otherwise, let pos be ! ToIntegerOrInfinity(numPos).
  7. Let len be the length of S.
  8. Let searchLen be the length of searchStr.
  9. Let start be the result of clamping pos between 0 and len - searchLen.
  10. If searchStr is the empty String, return 𝔽(start).
  11. For each integer i such that 0 ≤ istart, in descending order, do
    1. Let candidate be the substring of S from i to i + searchLen.
    2. If candidate is searchStr, return 𝔽(i).
  12. Return -1𝔽.
Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.12 String.prototype.localeCompare ( that [ , reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method returns a Number other than NaN representing the result of an implementation-defined locale-sensitive String comparison of the this value (converted to a String S) with that (converted to a String thatValue). The result is intended to correspond with a sort order of String values according to conventions of the host environment's current locale, and will be negative when S is ordered before thatValue, positive when S is ordered after thatValue, and zero in all other cases (representing no relative ordering between S and thatValue).

Before performing the comparisons, this method performs the following steps to prepare the Strings:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let thatValue be ? ToString(that).

The meaning of the optional second and third parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not assign any other interpretation to those parameter positions.

The actual return values are implementation-defined to permit encoding additional information in them, but this method, when considered as a method of two arguments, is required to be a consistent comparator defining a total ordering on the set of all Strings. This method is also required to recognize and honour canonical equivalence according to the Unicode Standard, including returning +0𝔽 when comparing distinguishable Strings that are canonically equivalent.

Note 1

This method itself is not directly suitable as an argument to Array.prototype.sort because the latter requires a function of two arguments.

Note 2

This method may rely on whatever language- and/or locale-sensitive comparison functionality is available to the ECMAScript environment from the host environment, and is intended to compare according to the conventions of the host environment's current locale. However, regardless of comparison capabilities, this method must recognize and honour canonical equivalence according to the Unicode Standard—for example, the following comparisons must all return +0𝔽:

// Å ANGSTROM SIGN vs.
// Å LATIN CAPITAL LETTER A + COMBINING RING ABOVE
"\u212B".localeCompare("A\u030A")

// Ω OHM SIGN vs.
// Ω GREEK CAPITAL LETTER OMEGA
"\u2126".localeCompare("\u03A9")

// ṩ LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE vs.
// ṩ LATIN SMALL LETTER S + COMBINING DOT ABOVE + COMBINING DOT BELOW
"\u1E69".localeCompare("s\u0307\u0323")

// ḍ̇ LATIN SMALL LETTER D WITH DOT ABOVE + COMBINING DOT BELOW vs.
// ḍ̇ LATIN SMALL LETTER D WITH DOT BELOW + COMBINING DOT ABOVE
"\u1E0B\u0323".localeCompare("\u1E0D\u0307")

// 가 HANGUL CHOSEONG KIYEOK + HANGUL JUNGSEONG A vs.
// 가 HANGUL SYLLABLE GA
"\u1100\u1161".localeCompare("\uAC00")

For a definition and discussion of canonical equivalence see the Unicode Standard, chapters 2 and 3, as well as Unicode Standard Annex #15, Unicode Normalization Forms and Unicode Technical Note #5, Canonical Equivalence in Applications. Also see Unicode Technical Standard #10, Unicode Collation Algorithm.

It is recommended that this method should not honour Unicode compatibility equivalents or compatibility decompositions as defined in the Unicode Standard, chapter 3, section 3.7.

Note 3

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.13 String.prototype.match ( regexp )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If regexp is neither undefined nor null, then
    1. Let matcher be ? GetMethod(regexp, @@match).
    2. If matcher is not undefined, then
      1. Return ? Call(matcher, regexp, « O »).
  3. Let S be ? ToString(O).
  4. Let rx be ? RegExpCreate(regexp, undefined).
  5. Return ? Invoke(rx, @@match, « S »).
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.14 String.prototype.matchAll ( regexp )

This method performs a regular expression match of the String representing the this value against regexp and returns an iterator. Each iteration result's value is an Array containing the results of the match, or null if the String did not match.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If regexp is neither undefined nor null, then
    1. Let isRegExp be ? IsRegExp(regexp).
    2. If isRegExp is true, then
      1. Let flags be ? Get(regexp, "flags").
      2. Perform ? RequireObjectCoercible(flags).
      3. If ? ToString(flags) does not contain "g", throw a TypeError exception.
    3. Let matcher be ? GetMethod(regexp, @@matchAll).
    4. If matcher is not undefined, then
      1. Return ? Call(matcher, regexp, « O »).
  3. Let S be ? ToString(O).
  4. Let rx be ? RegExpCreate(regexp, "g").
  5. Return ? Invoke(rx, @@matchAll, « S »).
Note 1
This method is intentionally generic, it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.
Note 2
Similarly to String.prototype.split, String.prototype.matchAll is designed to typically act without mutating its inputs.

22.1.3.15 String.prototype.normalize ( [ form ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. If form is undefined, let f be "NFC".
  4. Else, let f be ? ToString(form).
  5. If f is not one of "NFC", "NFD", "NFKC", or "NFKD", throw a RangeError exception.
  6. Let ns be the String value that is the result of normalizing S into the normalization form named by f as specified in the latest Unicode Standard, Normalization Forms.
  7. Return ns.
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.16 String.prototype.padEnd ( maxLength [ , fillString ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Return ? StringPaddingBuiltinsImpl(O, maxLength, fillString, end).

22.1.3.17 String.prototype.padStart ( maxLength [ , fillString ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Return ? StringPaddingBuiltinsImpl(O, maxLength, fillString, start).

22.1.3.17.1 StringPaddingBuiltinsImpl ( O, maxLength, fillString, placement )

The abstract operation StringPaddingBuiltinsImpl takes arguments O (an ECMAScript language value), maxLength (an ECMAScript language value), fillString (an ECMAScript language value), and placement (start or end) and returns either a normal completion containing a String or a throw completion. It performs the following steps when called:

  1. Let S be ? ToString(O).
  2. Let intMaxLength be (? ToLength(maxLength)).
  3. Let stringLength be the length of S.
  4. If intMaxLengthstringLength, return S.
  5. If fillString is undefined, set fillString to the String value consisting solely of the code unit 0x0020 (SPACE).
  6. Else, set fillString to ? ToString(fillString).
  7. Return StringPad(S, intMaxLength, fillString, placement).

22.1.3.17.2 StringPad ( S, maxLength, fillString, placement )

The abstract operation StringPad takes arguments S (a String), maxLength (a non-negative integer), fillString (a String), and placement (start or end) and returns a String. It performs the following steps when called:

  1. Let stringLength be the length of S.
  2. If maxLengthstringLength, return S.
  3. If fillString is the empty String, return S.
  4. Let fillLen be maxLength - stringLength.
  5. Let truncatedStringFiller be the String value consisting of repeated concatenations of fillString truncated to length fillLen.
  6. If placement is start, return the string-concatenation of truncatedStringFiller and S.
  7. Else, return the string-concatenation of S and truncatedStringFiller.
Note 1

The argument maxLength will be clamped such that it can be no smaller than the length of S.

Note 2

The argument fillString defaults to " " (the String value consisting of the code unit 0x0020 SPACE).

22.1.3.17.3 ToZeroPaddedDecimalString ( n, minLength )

The abstract operation ToZeroPaddedDecimalString takes arguments n (a non-negative integer) and minLength (a non-negative integer) and returns a String. It performs the following steps when called:

  1. Let S be the String representation of n, formatted as a decimal number.
  2. Return StringPad(S, minLength, "0", start).

22.1.3.18 String.prototype.repeat ( count )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let n be ? ToIntegerOrInfinity(count).
  4. If n < 0 or n = +∞, throw a RangeError exception.
  5. If n = 0, return the empty String.
  6. Return the String value that is made from n copies of S appended together.
Note 1

This method creates the String value consisting of the code units of the this value (converted to String) repeated count times.

Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.19 String.prototype.replace ( searchValue, replaceValue )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If searchValue is neither undefined nor null, then
    1. Let replacer be ? GetMethod(searchValue, @@replace).
    2. If replacer is not undefined, then
      1. Return ? Call(replacer, searchValue, « O, replaceValue »).
  3. Let string be ? ToString(O).
  4. Let searchString be ? ToString(searchValue).
  5. Let functionalReplace be IsCallable(replaceValue).
  6. If functionalReplace is false, then
    1. Set replaceValue to ? ToString(replaceValue).
  7. Let searchLength be the length of searchString.
  8. Let position be StringIndexOf(string, searchString, 0).
  9. If position = -1, return string.
  10. Let preceding be the substring of string from 0 to position.
  11. Let following be the substring of string from position + searchLength.
  12. If functionalReplace is true, then
    1. Let replacement be ? ToString(? Call(replaceValue, undefined, « searchString, 𝔽(position), string »)).
  13. Else,
    1. Assert: replaceValue is a String.
    2. Let captures be a new empty List.
    3. Let replacement be ! GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
  14. Return the string-concatenation of preceding, replacement, and following.
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.19.1 GetSubstitution ( matched, str, position, captures, namedCaptures, replacementTemplate )

The abstract operation GetSubstitution takes arguments matched (a String), str (a String), position (a non-negative integer), captures (a List of either Strings or undefined), namedCaptures (an Object or undefined), and replacementTemplate (a String) and returns either a normal completion containing a String or a throw completion. For the purposes of this abstract operation, a decimal digit is a code unit in the inclusive interval from 0x0030 (DIGIT ZERO) to 0x0039 (DIGIT NINE). It performs the following steps when called:

  1. Let stringLength be the length of str.
  2. Assert: positionstringLength.
  3. Let result be the empty String.
  4. Let templateRemainder be replacementTemplate.
  5. Repeat, while templateRemainder is not the empty String,
    1. NOTE: The following steps isolate ref (a prefix of templateRemainder), determine refReplacement (its replacement), and then append that replacement to result.
    2. If templateRemainder starts with "$$", then
      1. Let ref be "$$".
      2. Let refReplacement be "$".
    3. Else if templateRemainder starts with "$`", then
      1. Let ref be "$`".
      2. Let refReplacement be the substring of str from 0 to position.
    4. Else if templateRemainder starts with "$&", then
      1. Let ref be "$&".
      2. Let refReplacement be matched.
    5. Else if templateRemainder starts with "$'" (0x0024 (DOLLAR SIGN) followed by 0x0027 (APOSTROPHE)), then
      1. Let ref be "$'".
      2. Let matchLength be the length of matched.
      3. Let tailPos be position + matchLength.
      4. Let refReplacement be the substring of str from min(tailPos, stringLength).
      5. NOTE: tailPos can exceed stringLength only if this abstract operation was invoked by a call to the intrinsic @@replace method of %RegExp.prototype% on an object whose "exec" property is not the intrinsic %RegExp.prototype.exec%.
    6. Else if templateRemainder starts with "$" followed by 1 or more decimal digits, then
      1. If templateRemainder starts with "$" followed by 2 or more decimal digits, let digitCount be 2. Otherwise, let digitCount be 1.
      2. Let digits be the substring of templateRemainder from 1 to 1 + digitCount.
      3. Let index be (StringToNumber(digits)).
      4. Assert: 0 ≤ index ≤ 99.
      5. Let captureLen be the number of elements in captures.
      6. If index > captureLen and digitCount = 2, then
        1. NOTE: When a two-digit replacement pattern specifies an index exceeding the count of capturing groups, it is treated as a one-digit replacement pattern followed by a literal digit.
        2. Set digitCount to 1.
        3. Set digits to the substring of digits from 0 to 1.
        4. Set index to (StringToNumber(digits)).
      7. Let ref be the substring of templateRemainder from 0 to 1 + digitCount.
      8. If 1 ≤ indexcaptureLen, then
        1. Let capture be captures[index - 1].
        2. If capture is undefined, then
          1. Let refReplacement be the empty String.
        3. Else,
          1. Let refReplacement be capture.
      9. Else,
        1. Let refReplacement be ref.
    7. Else if templateRemainder starts with "$<", then
      1. Let gtPos be StringIndexOf(templateRemainder, ">", 0).
      2. If gtPos = -1 or namedCaptures is undefined, then
        1. Let ref be "$<".
        2. Let refReplacement be ref.
      3. Else,
        1. Let ref be the substring of templateRemainder from 0 to gtPos + 1.
        2. Let groupName be the substring of templateRemainder from 2 to gtPos.
        3. Assert: namedCaptures is an Object.
        4. Let capture be ? Get(namedCaptures, groupName).
        5. If capture is undefined, then
          1. Let refReplacement be the empty String.
        6. Else,
          1. Let refReplacement be ? ToString(capture).
    8. Else,
      1. Let ref be the substring of templateRemainder from 0 to 1.
      2. Let refReplacement be ref.
    9. Let refLength be the length of ref.
    10. Set templateRemainder to the substring of templateRemainder from refLength.
    11. Set result to the string-concatenation of result and refReplacement.
  6. Return result.

22.1.3.20 String.prototype.replaceAll ( searchValue, replaceValue )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If searchValue is neither undefined nor null, then
    1. Let isRegExp be ? IsRegExp(searchValue).
    2. If isRegExp is true, then
      1. Let flags be ? Get(searchValue, "flags").
      2. Perform ? RequireObjectCoercible(flags).
      3. If ? ToString(flags) does not contain "g", throw a TypeError exception.
    3. Let replacer be ? GetMethod(searchValue, @@replace).
    4. If replacer is not undefined, then
      1. Return ? Call(replacer, searchValue, « O, replaceValue »).
  3. Let string be ? ToString(O).
  4. Let searchString be ? ToString(searchValue).
  5. Let functionalReplace be IsCallable(replaceValue).
  6. If functionalReplace is false, then
    1. Set replaceValue to ? ToString(replaceValue).
  7. Let searchLength be the length of searchString.
  8. Let advanceBy be max(1, searchLength).
  9. Let matchPositions be a new empty List.
  10. Let position be StringIndexOf(string, searchString, 0).
  11. Repeat, while position ≠ -1,
    1. Append position to matchPositions.
    2. Set position to StringIndexOf(string, searchString, position + advanceBy).
  12. Let endOfLastMatch be 0.
  13. Let result be the empty String.
  14. For each element p of matchPositions, do
    1. Let preserved be the substring of string from endOfLastMatch to p.
    2. If functionalReplace is true, then
      1. Let replacement be ? ToString(? Call(replaceValue, undefined, « searchString, 𝔽(p), string »)).
    3. Else,
      1. Assert: replaceValue is a String.
      2. Let captures be a new empty List.
      3. Let replacement be ! GetSubstitution(searchString, string, p, captures, undefined, replaceValue).
    4. Set result to the string-concatenation of result, preserved, and replacement.
    5. Set endOfLastMatch to p + searchLength.
  15. If endOfLastMatch < the length of string, then
    1. Set result to the string-concatenation of result and the substring of string from endOfLastMatch.
  16. Return result.

22.1.3.21 String.prototype.search ( regexp )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If regexp is neither undefined nor null, then
    1. Let searcher be ? GetMethod(regexp, @@search).
    2. If searcher is not undefined, then
      1. Return ? Call(searcher, regexp, « O »).
  3. Let string be ? ToString(O).
  4. Let rx be ? RegExpCreate(regexp, undefined).
  5. Return ? Invoke(rx, @@search, « string »).
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.22 String.prototype.slice ( start, end )

This method returns a substring of the result of converting this object to a String, starting from index start and running to, but not including, index end (or through the end of the String if end is undefined). If start is negative, it is treated as sourceLength + start where sourceLength is the length of the String. If end is negative, it is treated as sourceLength + end where sourceLength is the length of the String. The result is a String value, not a String object.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let len be the length of S.
  4. Let intStart be ? ToIntegerOrInfinity(start).
  5. If intStart = -∞, let from be 0.
  6. Else if intStart < 0, let from be max(len + intStart, 0).
  7. Else, let from be min(intStart, len).
  8. If end is undefined, let intEnd be len; else let intEnd be ? ToIntegerOrInfinity(end).
  9. If intEnd = -∞, let to be 0.
  10. Else if intEnd < 0, let to be max(len + intEnd, 0).
  11. Else, let to be min(intEnd, len).
  12. If fromto, return the empty String.
  13. Return the substring of S from from to to.
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.23 String.prototype.split ( separator, limit )

This method returns an Array into which substrings of the result of converting this object to a String have been stored. The substrings are determined by searching from left to right for occurrences of separator; these occurrences are not part of any String in the returned array, but serve to divide up the String value. The value of separator may be a String of any length or it may be an object, such as a RegExp, that has a @@split method.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If separator is neither undefined nor null, then
    1. Let splitter be ? GetMethod(separator, @@split).
    2. If splitter is not undefined, then
      1. Return ? Call(splitter, separator, « O, limit »).
  3. Let S be ? ToString(O).
  4. If limit is undefined, let lim be 232 - 1; else let lim be (? ToUint32(limit)).
  5. Let R be ? ToString(separator).
  6. If lim = 0, then
    1. Return CreateArrayFromList(« »).
  7. If separator is undefined, then
    1. Return CreateArrayFromListS »).
  8. Let separatorLength be the length of R.
  9. If separatorLength = 0, then
    1. Let head be the substring of S from 0 to lim.
    2. Let codeUnits be a List consisting of the sequence of code units that are the elements of head.
    3. Return CreateArrayFromList(codeUnits).
  10. If S is the empty String, return CreateArrayFromListS »).
  11. Let substrings be a new empty List.
  12. Let i be 0.
  13. Let j be StringIndexOf(S, R, 0).
  14. Repeat, while j ≠ -1,
    1. Let T be the substring of S from i to j.
    2. Append T to substrings.
    3. If the number of elements in substrings is lim, return CreateArrayFromList(substrings).
    4. Set i to j + separatorLength.
    5. Set j to StringIndexOf(S, R, i).
  15. Let T be the substring of S from i.
  16. Append T to substrings.
  17. Return CreateArrayFromList(substrings).
Note 1

The value of separator may be an empty String. In this case, separator does not match the empty substring at the beginning or end of the input String, nor does it match the empty substring at the end of the previous separator match. If separator is the empty String, the String is split up into individual code unit elements; the length of the result array equals the length of the String, and each substring contains one code unit.

If the this value is (or converts to) the empty String, the result depends on whether separator can match the empty String. If it can, the result array contains no elements. Otherwise, the result array contains one element, which is the empty String.

If separator is undefined, then the result array contains just one String, which is the this value (converted to a String). If limit is not undefined, then the output array is truncated so that it contains no more than limit elements.

Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.24 String.prototype.startsWith ( searchString [ , position ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let isRegExp be ? IsRegExp(searchString).
  4. If isRegExp is true, throw a TypeError exception.
  5. Let searchStr be ? ToString(searchString).
  6. Let len be the length of S.
  7. If position is undefined, let pos be 0; else let pos be ? ToIntegerOrInfinity(position).
  8. Let start be the result of clamping pos between 0 and len.
  9. Let searchLength be the length of searchStr.
  10. If searchLength = 0, return true.
  11. Let end be start + searchLength.
  12. If end > len, return false.
  13. Let substring be the substring of S from start to end.
  14. If substring is searchStr, return true.
  15. Return false.
Note 1

This method returns true if the sequence of code units of searchString converted to a String is the same as the corresponding code units of this object (converted to a String) starting at index position. Otherwise it returns false.

Note 2

Throwing an exception if the first argument is a RegExp is specified in order to allow future editions to define extensions that allow such argument values.

Note 3

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.25 String.prototype.substring ( start, end )

This method returns a substring of the result of converting this object to a String, starting from index start and running to, but not including, index end of the String (or through the end of the String if end is undefined). The result is a String value, not a String object.

If either argument is NaN or negative, it is replaced with zero; if either argument is strictly greater than the length of the String, it is replaced with the length of the String.

If start is strictly greater than end, they are swapped.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let len be the length of S.
  4. Let intStart be ? ToIntegerOrInfinity(start).
  5. If end is undefined, let intEnd be len; else let intEnd be ? ToIntegerOrInfinity(end).
  6. Let finalStart be the result of clamping intStart between 0 and len.
  7. Let finalEnd be the result of clamping intEnd between 0 and len.
  8. Let from be min(finalStart, finalEnd).
  9. Let to be max(finalStart, finalEnd).
  10. Return the substring of S from from to to.
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.26 String.prototype.toLocaleLowerCase ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It works exactly the same as toLowerCase except that it is intended to yield a locale-sensitive result corresponding with conventions of the host environment's current locale. There will only be a difference in the few cases (such as Turkish) where the rules for that language conflict with the regular Unicode case mappings.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.27 String.prototype.toLocaleUpperCase ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It works exactly the same as toUpperCase except that it is intended to yield a locale-sensitive result corresponding with conventions of the host environment's current locale. There will only be a difference in the few cases (such as Turkish) where the rules for that language conflict with the regular Unicode case mappings.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.28 String.prototype.toLowerCase ( )

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let sText be StringToCodePoints(S).
  4. Let lowerText be the result of toLowercase(sText), according to the Unicode Default Case Conversion algorithm.
  5. Let L be CodePointsToString(lowerText).
  6. Return L.

The result must be derived according to the locale-insensitive case mappings in the Unicode Character Database (this explicitly includes not only the file UnicodeData.txt, but also all locale-insensitive mappings in the file SpecialCasing.txt that accompanies it).

Note 1

The case mapping of some code points may produce multiple code points. In this case the result String may not be the same length as the source String. Because both toUpperCase and toLowerCase have context-sensitive behaviour, the methods are not symmetrical. In other words, s.toUpperCase().toLowerCase() is not necessarily equal to s.toLowerCase().

Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.29 String.prototype.toString ( )

This method performs the following steps when called:

  1. Return ? ThisStringValue(this value).
Note

For a String object, this method happens to return the same thing as the valueOf method.

22.1.3.30 String.prototype.toUpperCase ( )

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It behaves in exactly the same way as String.prototype.toLowerCase, except that the String is mapped using the toUppercase algorithm of the Unicode Default Case Conversion.

Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.31 String.prototype.toWellFormed ( )

This method returns a String representation of this object with all leading surrogates and trailing surrogates that are not part of a surrogate pair replaced with U+FFFD (REPLACEMENT CHARACTER).

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let strLen be the length of S.
  4. Let k be 0.
  5. Let result be the empty String.
  6. Repeat, while k < strLen,
    1. Let cp be CodePointAt(S, k).
    2. If cp.[[IsUnpairedSurrogate]] is true, then
      1. Set result to the string-concatenation of result and 0xFFFD (REPLACEMENT CHARACTER).
    3. Else,
      1. Set result to the string-concatenation of result and UTF16EncodeCodePoint(cp.[[CodePoint]]).
    4. Set k to k + cp.[[CodeUnitCount]].
  7. Return result.

22.1.3.32 String.prototype.trim ( )

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It performs the following steps when called:

  1. Let S be the this value.
  2. Return ? TrimString(S, start+end).
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.32.1 TrimString ( string, where )

The abstract operation TrimString takes arguments string (an ECMAScript language value) and where (start, end, or start+end) and returns either a normal completion containing a String or a throw completion. It interprets string as a sequence of UTF-16 encoded code points, as described in 6.1.4. It performs the following steps when called:

  1. Let str be ? RequireObjectCoercible(string).
  2. Let S be ? ToString(str).
  3. If where is start, then
    1. Let T be the String value that is a copy of S with leading white space removed.
  4. Else if where is end, then
    1. Let T be the String value that is a copy of S with trailing white space removed.
  5. Else,
    1. Assert: where is start+end.
    2. Let T be the String value that is a copy of S with both leading and trailing white space removed.
  6. Return T.

The definition of white space is the union of WhiteSpace and LineTerminator. When determining whether a Unicode code point is in Unicode general category “Space_Separator” (“Zs”), code unit sequences are interpreted as UTF-16 encoded code point sequences as specified in 6.1.4.

22.1.3.33 String.prototype.trimEnd ( )

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It performs the following steps when called:

  1. Let S be the this value.
  2. Return ? TrimString(S, end).
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.34 String.prototype.trimStart ( )

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It performs the following steps when called:

  1. Let S be the this value.
  2. Return ? TrimString(S, start).
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.35 String.prototype.valueOf ( )

This method performs the following steps when called:

  1. Return ? ThisStringValue(this value).

22.1.3.35.1 ThisStringValue ( value )

The abstract operation ThisStringValue takes argument value (an ECMAScript language value) and returns either a normal completion containing a String or a throw completion. It performs the following steps when called:

  1. If value is a String, return value.
  2. If value is an Object and value has a [[StringData]] internal slot, then
    1. Let s be value.[[StringData]].
    2. Assert: s is a String.
    3. Return s.
  3. Throw a TypeError exception.

22.1.3.36 String.prototype [ @@iterator ] ( )

This method returns an Iterator object (27.1.1.2) that iterates over the code points of a String value, returning each code point as a String value.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let s be ? ToString(O).
  3. Let closure be a new Abstract Closure with no parameters that captures s and performs the following steps when called:
    1. Let len be the length of s.
    2. Let position be 0.
    3. Repeat, while position < len,
      1. Let cp be CodePointAt(s, position).
      2. Let nextIndex be position + cp.[[CodeUnitCount]].
      3. Let resultString be the substring of s from position to nextIndex.
      4. Set position to nextIndex.
      5. Perform ? GeneratorYield(CreateIterResultObject(resultString, false)).
    4. Return undefined.
  4. Return CreateIteratorFromClosure(closure, "%StringIteratorPrototype%", %StringIteratorPrototype%).

The value of the "name" property of this method is "[Symbol.iterator]".

22.1.4 Properties of String Instances

String instances are String exotic objects and have the internal methods specified for such objects. String instances inherit properties from the String prototype object. String instances also have a [[StringData]] internal slot. The [[StringData]] internal slot is the String value represented by this String object.

String instances have a "length" property, and a set of enumerable properties with integer-indexed names.

22.1.4.1 length

The number of elements in the String value represented by this String object.

Once a String object is initialized, this property is unchanging. It has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

22.1.5 String Iterator Objects

A String Iterator is an object, that represents a specific iteration over some specific String instance object. There is not a named constructor for String Iterator objects. Instead, String iterator objects are created by calling certain methods of String instance objects.

22.1.5.1 The %StringIteratorPrototype% Object

The %StringIteratorPrototype% object:

  • has properties that are inherited by all String Iterator Objects.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %IteratorPrototype%.
  • has the following properties:

22.1.5.1.1 %StringIteratorPrototype%.next ( )

  1. Return ? GeneratorResume(this value, empty, "%StringIteratorPrototype%").

22.1.5.1.2 %StringIteratorPrototype% [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "String Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

22.2 RegExp (Regular Expression) Objects

A RegExp object contains a regular expression and the associated flags.

Note

The form and functionality of regular expressions is modelled after the regular expression facility in the Perl 5 programming language.

22.2.1 Patterns

The RegExp constructor applies the following grammar to the input pattern String. An error occurs if the grammar cannot interpret the String as an expansion of Pattern.

Syntax

Pattern[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Disjunction[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] | Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: [empty] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Assertion[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Quantifier Assertion[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: ^ $ \b \B (?= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) Quantifier :: QuantifierPrefix QuantifierPrefix ? QuantifierPrefix :: * + ? { DecimalDigits[~Sep] } { DecimalDigits[~Sep] ,} { DecimalDigits[~Sep] , DecimalDigits[~Sep] } Atom[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: PatternCharacter . \ AtomEscape[?UnicodeMode, ?NamedCaptureGroups] CharacterClass[?UnicodeMode, ?UnicodeSetsMode] ( GroupSpecifier[?UnicodeMode]opt Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?: Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) SyntaxCharacter :: one of ^ $ \ . * + ? ( ) [ ] { } | PatternCharacter :: SourceCharacter but not SyntaxCharacter AtomEscape[UnicodeMode, NamedCaptureGroups] :: DecimalEscape CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] [+NamedCaptureGroups] k GroupName[?UnicodeMode] CharacterEscape[UnicodeMode] :: ControlEscape c AsciiLetter 0 [lookahead ∉ DecimalDigit] HexEscapeSequence RegExpUnicodeEscapeSequence[?UnicodeMode] IdentityEscape[?UnicodeMode] ControlEscape :: one of f n r t v GroupSpecifier[UnicodeMode] :: ? GroupName[?UnicodeMode] GroupName[UnicodeMode] :: < RegExpIdentifierName[?UnicodeMode] > RegExpIdentifierName[UnicodeMode] :: RegExpIdentifierStart[?UnicodeMode] RegExpIdentifierName[?UnicodeMode] RegExpIdentifierPart[?UnicodeMode] RegExpIdentifierStart[UnicodeMode] :: IdentifierStartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart[UnicodeMode] :: IdentifierPartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpUnicodeEscapeSequence[UnicodeMode] :: [+UnicodeMode] u HexLeadSurrogate \u HexTrailSurrogate [+UnicodeMode] u HexLeadSurrogate [+UnicodeMode] u HexTrailSurrogate [+UnicodeMode] u HexNonSurrogate [~UnicodeMode] u Hex4Digits [+UnicodeMode] u{ CodePoint } UnicodeLeadSurrogate :: any Unicode code point in the inclusive interval from U+D800 to U+DBFF UnicodeTrailSurrogate :: any Unicode code point in the inclusive interval from U+DC00 to U+DFFF

Each \u HexTrailSurrogate for which the choice of associated u HexLeadSurrogate is ambiguous shall be associated with the nearest possible u HexLeadSurrogate that would otherwise have no corresponding \u HexTrailSurrogate.

HexLeadSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xD800 to 0xDBFF HexTrailSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xDC00 to 0xDFFF HexNonSurrogate :: Hex4Digits but only if the MV of Hex4Digits is not in the inclusive interval from 0xD800 to 0xDFFF IdentityEscape[UnicodeMode] :: [+UnicodeMode] SyntaxCharacter [+UnicodeMode] / [~UnicodeMode] SourceCharacter but not UnicodeIDContinue DecimalEscape :: NonZeroDigit DecimalDigits[~Sep]opt [lookahead ∉ DecimalDigit] CharacterClassEscape[UnicodeMode] :: d D s S w W [+UnicodeMode] p{ UnicodePropertyValueExpression } [+UnicodeMode] P{ UnicodePropertyValueExpression } UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue LoneUnicodePropertyNameOrValue UnicodePropertyName :: UnicodePropertyNameCharacters UnicodePropertyNameCharacters :: UnicodePropertyNameCharacter UnicodePropertyNameCharactersopt UnicodePropertyValue :: UnicodePropertyValueCharacters LoneUnicodePropertyNameOrValue :: UnicodePropertyValueCharacters UnicodePropertyValueCharacters :: UnicodePropertyValueCharacter UnicodePropertyValueCharactersopt UnicodePropertyValueCharacter :: UnicodePropertyNameCharacter DecimalDigit UnicodePropertyNameCharacter :: AsciiLetter _ CharacterClass[UnicodeMode, UnicodeSetsMode] :: [ [lookahead ≠ ^] ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] [^ ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] ClassContents[UnicodeMode, UnicodeSetsMode] :: [empty] [~UnicodeSetsMode] NonemptyClassRanges[?UnicodeMode] [+UnicodeSetsMode] ClassSetExpression NonemptyClassRanges[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtom[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtom[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] NonemptyClassRangesNoDash[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] ClassAtom[UnicodeMode] :: - ClassAtomNoDash[?UnicodeMode] ClassAtomNoDash[UnicodeMode] :: SourceCharacter but not one of \ or ] or - \ ClassEscape[?UnicodeMode] ClassEscape[UnicodeMode] :: b [+UnicodeMode] - CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] ClassSetExpression :: ClassUnion ClassIntersection ClassSubtraction ClassUnion :: ClassSetRange ClassUnionopt ClassSetOperand ClassUnionopt ClassIntersection :: ClassSetOperand && [lookahead ≠ &] ClassSetOperand ClassIntersection && [lookahead ≠ &] ClassSetOperand ClassSubtraction :: ClassSetOperand -- ClassSetOperand ClassSubtraction -- ClassSetOperand ClassSetRange :: ClassSetCharacter - ClassSetCharacter ClassSetOperand :: NestedClass ClassStringDisjunction ClassSetCharacter NestedClass :: [ [lookahead ≠ ^] ClassContents[+UnicodeMode, +UnicodeSetsMode] ] [^ ClassContents[+UnicodeMode, +UnicodeSetsMode] ] \ CharacterClassEscape[+UnicodeMode] Note 1

The first two lines here are equivalent to CharacterClass.

ClassStringDisjunction :: \q{ ClassStringDisjunctionContents } ClassStringDisjunctionContents :: ClassString ClassString | ClassStringDisjunctionContents ClassString :: [empty] NonEmptyClassString NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt ClassSetCharacter :: [lookahead ∉ ClassSetReservedDoublePunctuator] SourceCharacter but not ClassSetSyntaxCharacter \ CharacterEscape[+UnicodeMode] \ ClassSetReservedPunctuator \b ClassSetReservedDoublePunctuator :: one of && !! ## $$ %% ** ++ ,, .. :: ;; << == >> ?? @@ ^^ `` ~~ ClassSetSyntaxCharacter :: one of ( ) [ ] { } / - \ | ClassSetReservedPunctuator :: one of & - ! # % , : ; < = > @ ` ~ Note 2

A number of productions in this section are given alternative definitions in section B.1.2.

22.2.1.1 Static Semantics: Early Errors

Note

This section is amended in B.1.2.1.

Pattern :: Disjunction QuantifierPrefix :: { DecimalDigits , DecimalDigits } AtomEscape :: k GroupName AtomEscape :: DecimalEscape NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents RegExpIdentifierStart :: \ RegExpUnicodeEscapeSequence RegExpIdentifierStart :: UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart :: \ RegExpUnicodeEscapeSequence RegExpIdentifierPart :: UnicodeLeadSurrogate UnicodeTrailSurrogate UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue UnicodePropertyValueExpression :: LoneUnicodePropertyNameOrValue CharacterClassEscape :: P{ UnicodePropertyValueExpression } CharacterClass :: [^ ClassContents ] NestedClass :: [^ ClassContents ] ClassSetRange :: ClassSetCharacter - ClassSetCharacter

22.2.1.2 Static Semantics: CountLeftCapturingParensWithin ( node )

The abstract operation CountLeftCapturingParensWithin takes argument node (a Parse Node) and returns a non-negative integer. It returns the number of left-capturing parentheses in node. A left-capturing parenthesis is any ( pattern character that is matched by the ( terminal of the Atom :: ( GroupSpecifieropt Disjunction ) production.

Note

This section is amended in B.1.2.2.

It performs the following steps when called:

  1. Assert: node is an instance of a production in the RegExp Pattern grammar.
  2. Return the number of Atom :: ( GroupSpecifieropt Disjunction ) Parse Nodes contained within node.

22.2.1.3 Static Semantics: CountLeftCapturingParensBefore ( node )

The abstract operation CountLeftCapturingParensBefore takes argument node (a Parse Node) and returns a non-negative integer. It returns the number of left-capturing parentheses within the enclosing pattern that occur to the left of node.

Note

This section is amended in B.1.2.2.

It performs the following steps when called:

  1. Assert: node is an instance of a production in the RegExp Pattern grammar.
  2. Let pattern be the Pattern containing node.
  3. Return the number of Atom :: ( GroupSpecifieropt Disjunction ) Parse Nodes contained within pattern that either occur before node or contain node.

22.2.1.4 Static Semantics: CapturingGroupNumber

The syntax-directed operation CapturingGroupNumber takes no arguments and returns a positive integer.

Note

This section is amended in B.1.2.1.

It is defined piecewise over the following productions:

DecimalEscape :: NonZeroDigit
  1. Return the MV of NonZeroDigit.
DecimalEscape :: NonZeroDigit DecimalDigits
  1. Let n be the number of code points in DecimalDigits.
  2. Return (the MV of NonZeroDigit × 10n plus the MV of DecimalDigits).

The definitions of “the MV of NonZeroDigit” and “the MV of DecimalDigits” are in 12.9.3.

22.2.1.5 Static Semantics: IsCharacterClass

The syntax-directed operation IsCharacterClass takes no arguments and returns a Boolean.

Note

This section is amended in B.1.2.3.

It is defined piecewise over the following productions:

ClassAtom :: - ClassAtomNoDash :: SourceCharacter but not one of \ or ] or - ClassEscape :: b - CharacterEscape
  1. Return false.
ClassEscape :: CharacterClassEscape
  1. Return true.

22.2.1.6 Static Semantics: CharacterValue

The syntax-directed operation CharacterValue takes no arguments and returns a non-negative integer.

Note 1

This section is amended in B.1.2.4.

It is defined piecewise over the following productions:

ClassAtom :: -
  1. Return the numeric value of U+002D (HYPHEN-MINUS).
ClassAtomNoDash :: SourceCharacter but not one of \ or ] or -
  1. Let ch be the code point matched by SourceCharacter.
  2. Return the numeric value of ch.
ClassEscape :: b
  1. Return the numeric value of U+0008 (BACKSPACE).
ClassEscape :: -
  1. Return the numeric value of U+002D (HYPHEN-MINUS).
CharacterEscape :: ControlEscape
  1. Return the numeric value according to Table 65.
Table 65: ControlEscape Code Point Values
ControlEscape Numeric Value Code Point Unicode Name Symbol
t 9 U+0009 CHARACTER TABULATION <HT>
n 10 U+000A LINE FEED (LF) <LF>
v 11 U+000B LINE TABULATION <VT>
f 12 U+000C FORM FEED (FF) <FF>
r 13 U+000D CARRIAGE RETURN (CR) <CR>
CharacterEscape :: c AsciiLetter
  1. Let ch be the code point matched by AsciiLetter.
  2. Let i be the numeric value of ch.
  3. Return the remainder of dividing i by 32.
CharacterEscape :: 0 [lookahead ∉ DecimalDigit]
  1. Return the numeric value of U+0000 (NULL).
Note 2

\0 represents the <NUL> character and cannot be followed by a decimal digit.

CharacterEscape :: HexEscapeSequence
  1. Return the MV of HexEscapeSequence.
RegExpUnicodeEscapeSequence :: u HexLeadSurrogate \u HexTrailSurrogate
  1. Let lead be the CharacterValue of HexLeadSurrogate.
  2. Let trail be the CharacterValue of HexTrailSurrogate.
  3. Let cp be UTF16SurrogatePairToCodePoint(lead, trail).
  4. Return the numeric value of cp.
RegExpUnicodeEscapeSequence :: u Hex4Digits
  1. Return the MV of Hex4Digits.
RegExpUnicodeEscapeSequence :: u{ CodePoint }
  1. Return the MV of CodePoint.
HexLeadSurrogate :: Hex4Digits HexTrailSurrogate :: Hex4Digits HexNonSurrogate :: Hex4Digits
  1. Return the MV of Hex4Digits.
CharacterEscape :: IdentityEscape
  1. Let ch be the code point matched by IdentityEscape.
  2. Return the numeric value of ch.
ClassSetCharacter :: SourceCharacter but not ClassSetSyntaxCharacter
  1. Let ch be the code point matched by SourceCharacter.
  2. Return the numeric value of ch.
ClassSetCharacter :: \ ClassSetReservedPunctuator
  1. Let ch be the code point matched by ClassSetReservedPunctuator.
  2. Return the numeric value of ch.
ClassSetCharacter :: \b
  1. Return the numeric value of U+0008 (BACKSPACE).

22.2.1.7 Static Semantics: MayContainStrings

The syntax-directed operation MayContainStrings takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

CharacterClassEscape :: d D s S w W P{ UnicodePropertyValueExpression } UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue NestedClass :: [^ ClassContents ] ClassContents :: [empty] NonemptyClassRanges ClassSetOperand :: ClassSetCharacter
  1. Return false.
UnicodePropertyValueExpression :: LoneUnicodePropertyNameOrValue
  1. If the source text matched by LoneUnicodePropertyNameOrValue is a binary property of strings listed in the “Property name” column of Table 69, return true.
  2. Return false.
ClassUnion :: ClassSetRange ClassUnionopt
  1. If the ClassUnion is present, return MayContainStrings of the ClassUnion.
  2. Return false.
ClassUnion :: ClassSetOperand ClassUnionopt
  1. If MayContainStrings of the ClassSetOperand is true, return true.
  2. If ClassUnion is present, return MayContainStrings of the ClassUnion.
  3. Return false.
ClassIntersection :: ClassSetOperand && ClassSetOperand
  1. If MayContainStrings of the first ClassSetOperand is false, return false.
  2. If MayContainStrings of the second ClassSetOperand is false, return false.
  3. Return true.
ClassIntersection :: ClassIntersection && ClassSetOperand
  1. If MayContainStrings of the ClassIntersection is false, return false.
  2. If MayContainStrings of the ClassSetOperand is false, return false.
  3. Return true.
ClassSubtraction :: ClassSetOperand -- ClassSetOperand
  1. Return MayContainStrings of the first ClassSetOperand.
ClassSubtraction :: ClassSubtraction -- ClassSetOperand
  1. Return MayContainStrings of the ClassSubtraction.
ClassStringDisjunctionContents :: ClassString | ClassStringDisjunctionContents
  1. If MayContainStrings of the ClassString is true, return true.
  2. Return MayContainStrings of the ClassStringDisjunctionContents.
ClassString :: [empty]
  1. Return true.
ClassString :: NonEmptyClassString
  1. Return MayContainStrings of the NonEmptyClassString.
NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt
  1. If NonEmptyClassString is present, return true.
  2. Return false.

22.2.1.8 Static Semantics: GroupSpecifiersThatMatch ( thisGroupName )

The abstract operation GroupSpecifiersThatMatch takes argument thisGroupName (a GroupName Parse Node) and returns a List of GroupSpecifier Parse Nodes. It performs the following steps when called:

  1. Let name be the CapturingGroupName of thisGroupName.
  2. Let pattern be the Pattern containing thisGroupName.
  3. Let result be a new empty List.
  4. For each GroupSpecifier gs that pattern contains, do
    1. If the CapturingGroupName of gs is name, then
      1. Append gs to result.
  5. Return result.

22.2.1.9 Static Semantics: CapturingGroupName

The syntax-directed operation CapturingGroupName takes no arguments and returns a String. It is defined piecewise over the following productions:

GroupName :: < RegExpIdentifierName >
  1. Let idTextUnescaped be RegExpIdentifierCodePoints of RegExpIdentifierName.
  2. Return CodePointsToString(idTextUnescaped).

22.2.1.10 Static Semantics: RegExpIdentifierCodePoints

The syntax-directed operation RegExpIdentifierCodePoints takes no arguments and returns a List of code points. It is defined piecewise over the following productions:

RegExpIdentifierName :: RegExpIdentifierStart
  1. Let cp be RegExpIdentifierCodePoint of RegExpIdentifierStart.
  2. Return « cp ».
RegExpIdentifierName :: RegExpIdentifierName RegExpIdentifierPart
  1. Let cps be RegExpIdentifierCodePoints of the derived RegExpIdentifierName.
  2. Let cp be RegExpIdentifierCodePoint of RegExpIdentifierPart.
  3. Return the list-concatenation of cps and « cp ».

22.2.1.11 Static Semantics: RegExpIdentifierCodePoint

The syntax-directed operation RegExpIdentifierCodePoint takes no arguments and returns a code point. It is defined piecewise over the following productions:

RegExpIdentifierStart :: IdentifierStartChar
  1. Return the code point matched by IdentifierStartChar.
RegExpIdentifierPart :: IdentifierPartChar
  1. Return the code point matched by IdentifierPartChar.
RegExpIdentifierStart :: \ RegExpUnicodeEscapeSequence RegExpIdentifierPart :: \ RegExpUnicodeEscapeSequence
  1. Return the code point whose numeric value is the CharacterValue of RegExpUnicodeEscapeSequence.
RegExpIdentifierStart :: UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart :: UnicodeLeadSurrogate UnicodeTrailSurrogate
  1. Let lead be the code unit whose numeric value is the numeric value of the code point matched by UnicodeLeadSurrogate.
  2. Let trail be the code unit whose numeric value is the numeric value of the code point matched by UnicodeTrailSurrogate.
  3. Return UTF16SurrogatePairToCodePoint(lead, trail).

22.2.2 Pattern Semantics

A regular expression pattern is converted into an Abstract Closure using the process described below. An implementation is encouraged to use more efficient algorithms than the ones listed below, as long as the results are the same. The Abstract Closure is used as the value of a RegExp object's [[RegExpMatcher]] internal slot.

A Pattern is a BMP pattern if its associated flags contain neither a u nor a v. Otherwise, it is a Unicode pattern. A BMP pattern matches against a String interpreted as consisting of a sequence of 16-bit values that are Unicode code points in the range of the Basic Multilingual Plane. A Unicode pattern matches against a String interpreted as consisting of Unicode code points encoded using UTF-16. In the context of describing the behaviour of a BMP pattern “character” means a single 16-bit Unicode BMP code point. In the context of describing the behaviour of a Unicode pattern “character” means a UTF-16 encoded code point (6.1.4). In either context, “character value” means the numeric value of the corresponding non-encoded code point.

The syntax and semantics of Pattern is defined as if the source text for the Pattern was a List of SourceCharacter values where each SourceCharacter corresponds to a Unicode code point. If a BMP pattern contains a non-BMP SourceCharacter the entire pattern is encoded using UTF-16 and the individual code units of that encoding are used as the elements of the List.

Note

For example, consider a pattern expressed in source text as the single non-BMP character U+1D11E (MUSICAL SYMBOL G CLEF). Interpreted as a Unicode pattern, it would be a single element (character) List consisting of the single code point U+1D11E. However, interpreted as a BMP pattern, it is first UTF-16 encoded to produce a two element List consisting of the code units 0xD834 and 0xDD1E.

Patterns are passed to the RegExp constructor as ECMAScript String values in which non-BMP characters are UTF-16 encoded. For example, the single character MUSICAL SYMBOL G CLEF pattern, expressed as a String value, is a String of length 2 whose elements were the code units 0xD834 and 0xDD1E. So no further translation of the string would be necessary to process it as a BMP pattern consisting of two pattern characters. However, to process it as a Unicode pattern UTF16SurrogatePairToCodePoint must be used in producing a List whose sole element is a single pattern character, the code point U+1D11E.

An implementation may not actually perform such translations to or from UTF-16, but the semantics of this specification requires that the result of pattern matching be as if such translations were performed.

22.2.2.1 Notation

The descriptions below use the following internal data structures:

  • A CharSetElement is one of the two following entities:
    • If rer.[[UnicodeSets]] is false, then a CharSetElement is a character in the sense of the Pattern Semantics above.
    • If rer.[[UnicodeSets]] is true, then a CharSetElement is a sequence whose elements are characters in the sense of the Pattern Semantics above. This includes the empty sequence, sequences of one character, and sequences of more than one character. For convenience, when working with CharSetElements of this kind, an individual character is treated interchangeably with a sequence of one character.
  • A CharSet is a mathematical set of CharSetElements.
  • A CaptureRange is a Record { [[StartIndex]], [[EndIndex]] } that represents the range of characters included in a capture, where [[StartIndex]] is an integer representing the start index (inclusive) of the range within Input, and [[EndIndex]] is an integer representing the end index (exclusive) of the range within Input. For any CaptureRange, these indices must satisfy the invariant that [[StartIndex]][[EndIndex]].
  • A MatchState is a Record { [[Input]], [[EndIndex]], [[Captures]] } where [[Input]] is a List of characters representing the String being matched, [[EndIndex]] is an integer, and [[Captures]] is a List of values, one for each left-capturing parenthesis in the pattern. States are used to represent partial match states in the regular expression matching algorithms. The [[EndIndex]] is one plus the index of the last input character matched so far by the pattern, while [[Captures]] holds the results of capturing parentheses. The nth element of [[Captures]] is either a CaptureRange representing the range of characters captured by the nth set of capturing parentheses, or undefined if the nth set of capturing parentheses hasn't been reached yet. Due to backtracking, many States may be in use at any time during the matching process.
  • A MatchResult is either a MatchState or the special token failure that indicates that the match failed.
  • A MatcherContinuation is an Abstract Closure that takes one MatchState argument and returns a MatchResult result. The MatcherContinuation attempts to match the remaining portion (specified by the closure's captured values) of the pattern against Input, starting at the intermediate state given by its MatchState argument. If the match succeeds, the MatcherContinuation returns the final MatchState that it reached; if the match fails, the MatcherContinuation returns failure.
  • A Matcher is an Abstract Closure that takes two arguments—a MatchState and a MatcherContinuation—and returns a MatchResult result. A Matcher attempts to match a middle subpattern (specified by the closure's captured values) of the pattern against the MatchState's [[Input]], starting at the intermediate state given by its MatchState argument. The MatcherContinuation argument should be a closure that matches the rest of the pattern. After matching the subpattern of a pattern to obtain a new MatchState, the Matcher then calls MatcherContinuation on that new MatchState to test if the rest of the pattern can match as well. If it can, the Matcher returns the MatchState returned by MatcherContinuation; if not, the Matcher may try different choices at its choice points, repeatedly calling MatcherContinuation until it either succeeds or all possibilities have been exhausted.

22.2.2.1.1 RegExp Records

A RegExp Record is a Record value used to store information about a RegExp that is needed during compilation and possibly during matching.

It has the following fields:

Table 66: RegExp Record Fields
Field Name Value Meaning
[[IgnoreCase]] a Boolean indicates whether "i" appears in the RegExp's flags
[[Multiline]] a Boolean indicates whether "m" appears in the RegExp's flags
[[DotAll]] a Boolean indicates whether "s" appears in the RegExp's flags
[[Unicode]] a Boolean indicates whether "u" appears in the RegExp's flags
[[UnicodeSets]] a Boolean indicates whether "v" appears in the RegExp's flags
[[CapturingGroupsCount]] a non-negative integer the number of left-capturing parentheses in the RegExp's pattern

22.2.2.2 Runtime Semantics: CompilePattern

The syntax-directed operation CompilePattern takes argument rer (a RegExp Record) and returns an Abstract Closure that takes a List of characters and a non-negative integer and returns a MatchResult. It is defined piecewise over the following productions:

Pattern :: Disjunction
  1. Let m be CompileSubpattern of Disjunction with arguments rer and forward.
  2. Return a new Abstract Closure with parameters (Input, index) that captures rer and m and performs the following steps when called:
    1. Assert: Input is a List of characters.
    2. Assert: 0 ≤ index ≤ the number of elements in Input.
    3. Let c be a new MatcherContinuation with parameters (y) that captures nothing and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Return y.
    4. Let cap be a List of rer.[[CapturingGroupsCount]] undefined values, indexed 1 through rer.[[CapturingGroupsCount]].
    5. Let x be the MatchState { [[Input]]: Input, [[EndIndex]]: index, [[Captures]]: cap }.
    6. Return m(x, c).
Note

A Pattern compiles to an Abstract Closure value. RegExpBuiltinExec can then apply this procedure to a List of characters and an offset within that List to determine whether the pattern would match starting at exactly that offset within the List, and, if it does match, what the values of the capturing parentheses would be. The algorithms in 22.2.2 are designed so that compiling a pattern may throw a SyntaxError exception; on the other hand, once the pattern is successfully compiled, applying the resulting Abstract Closure to find a match in a List of characters cannot throw an exception (except for any implementation-defined exceptions that can occur anywhere such as out-of-memory).

22.2.2.3 Runtime Semantics: CompileSubpattern

The syntax-directed operation CompileSubpattern takes arguments rer (a RegExp Record) and direction (forward or backward) and returns a Matcher.

Note 1

This section is amended in B.1.2.5.

It is defined piecewise over the following productions:

Disjunction :: Alternative | Disjunction
  1. Let m1 be CompileSubpattern of Alternative with arguments rer and direction.
  2. Let m2 be CompileSubpattern of Disjunction with arguments rer and direction.
  3. Return MatchTwoAlternatives(m1, m2).
Note 2

The | regular expression operator separates two alternatives. The pattern first tries to match the left Alternative (followed by the sequel of the regular expression); if it fails, it tries to match the right Disjunction (followed by the sequel of the regular expression). If the left Alternative, the right Disjunction, and the sequel all have choice points, all choices in the sequel are tried before moving on to the next choice in the left Alternative. If choices in the left Alternative are exhausted, the right Disjunction is tried instead of the left Alternative. Any capturing parentheses inside a portion of the pattern skipped by | produce undefined values instead of Strings. Thus, for example,

/a|ab/.exec("abc")

returns the result "a" and not "ab". Moreover,

/((a)|(ab))((c)|(bc))/.exec("abc")

returns the array

["abc", "a", "a", undefined, "bc", undefined, "bc"]

and not

["abc", "ab", undefined, "ab", "c", "c", undefined]

The order in which the two alternatives are tried is independent of the value of direction.

Alternative :: [empty]
  1. Return EmptyMatcher().
Alternative :: Alternative Term
  1. Let m1 be CompileSubpattern of Alternative with arguments rer and direction.
  2. Let m2 be CompileSubpattern of Term with arguments rer and direction.
  3. Return MatchSequence(m1, m2, direction).
Note 3

Consecutive Terms try to simultaneously match consecutive portions of Input. When direction is forward, if the left Alternative, the right Term, and the sequel of the regular expression all have choice points, all choices in the sequel are tried before moving on to the next choice in the right Term, and all choices in the right Term are tried before moving on to the next choice in the left Alternative. When direction is backward, the evaluation order of Alternative and Term are reversed.

Term :: Assertion
  1. Return CompileAssertion of Assertion with argument rer.
Note 4

The resulting Matcher is independent of direction.

Term :: Atom
  1. Return CompileAtom of Atom with arguments rer and direction.
Term :: Atom Quantifier
  1. Let m be CompileAtom of Atom with arguments rer and direction.
  2. Let q be CompileQuantifier of Quantifier.
  3. Assert: q.[[Min]]q.[[Max]].
  4. Let parenIndex be CountLeftCapturingParensBefore(Term).
  5. Let parenCount be CountLeftCapturingParensWithin(Atom).
  6. Return a new Matcher with parameters (x, c) that captures m, q, parenIndex, and parenCount and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Return RepeatMatcher(m, q.[[Min]], q.[[Max]], q.[[Greedy]], x, c, parenIndex, parenCount).

22.2.2.3.1 RepeatMatcher ( m, min, max, greedy, x, c, parenIndex, parenCount )

The abstract operation RepeatMatcher takes arguments m (a Matcher), min (a non-negative integer), max (a non-negative integer or +∞), greedy (a Boolean), x (a MatchState), c (a MatcherContinuation), parenIndex (a non-negative integer), and parenCount (a non-negative integer) and returns a MatchResult. It performs the following steps when called:

  1. If max = 0, return c(x).
  2. Let d be a new MatcherContinuation with parameters (y) that captures m, min, max, greedy, x, c, parenIndex, and parenCount and performs the following steps when called:
    1. Assert: y is a MatchState.
    2. If min = 0 and y.[[EndIndex]] = x.[[EndIndex]], return failure.
    3. If min = 0, let min2 be 0; otherwise let min2 be min - 1.
    4. If max = +∞, let max2 be +∞; otherwise let max2 be max - 1.
    5. Return RepeatMatcher(m, min2, max2, greedy, y, c, parenIndex, parenCount).
  3. Let cap be a copy of x.[[Captures]].
  4. For each integer k in the inclusive interval from parenIndex + 1 to parenIndex + parenCount, set cap[k] to undefined.
  5. Let Input be x.[[Input]].
  6. Let e be x.[[EndIndex]].
  7. Let xr be the MatchState { [[Input]]: Input, [[EndIndex]]: e, [[Captures]]: cap }.
  8. If min ≠ 0, return m(xr, d).
  9. If greedy is false, then
    1. Let z be c(x).
    2. If z is not failure, return z.
    3. Return m(xr, d).
  10. Let z be m(xr, d).
  11. If z is not failure, return z.
  12. Return c(x).
Note 1

An Atom followed by a Quantifier is repeated the number of times specified by the Quantifier. A Quantifier can be non-greedy, in which case the Atom pattern is repeated as few times as possible while still matching the sequel, or it can be greedy, in which case the Atom pattern is repeated as many times as possible while still matching the sequel. The Atom pattern is repeated rather than the input character sequence that it matches, so different repetitions of the Atom can match different input substrings.

Note 2

If the Atom and the sequel of the regular expression all have choice points, the Atom is first matched as many (or as few, if non-greedy) times as possible. All choices in the sequel are tried before moving on to the next choice in the last repetition of Atom. All choices in the last (nth) repetition of Atom are tried before moving on to the next choice in the next-to-last (n - 1)st repetition of Atom; at which point it may turn out that more or fewer repetitions of Atom are now possible; these are exhausted (again, starting with either as few or as many as possible) before moving on to the next choice in the (n - 1)st repetition of Atom and so on.

Compare

/a[a-z]{2,4}/.exec("abcdefghi")

which returns "abcde" with

/a[a-z]{2,4}?/.exec("abcdefghi")

which returns "abc".

Consider also

/(aa|aabaac|ba|b|c)*/.exec("aabaac")

which, by the choice point ordering above, returns the array

["aaba", "ba"]

and not any of:

["aabaac", "aabaac"]
["aabaac", "c"]

The above ordering of choice points can be used to write a regular expression that calculates the greatest common divisor of two numbers (represented in unary notation). The following example calculates the gcd of 10 and 15:

"aaaaaaaaaa,aaaaaaaaaaaaaaa".replace(/^(a+)\1*,\1+$/, "$1")

which returns the gcd in unary notation "aaaaa".

Note 3

Step 4 of the RepeatMatcher clears Atom's captures each time Atom is repeated. We can see its behaviour in the regular expression

/(z)((a+)?(b+)?(c))*/.exec("zaacbbbcac")

which returns the array

["zaacbbbcac", "z", "ac", "a", undefined, "c"]

and not

["zaacbbbcac", "z", "ac", "a", "bbb", "c"]

because each iteration of the outermost * clears all captured Strings contained in the quantified Atom, which in this case includes capture Strings numbered 2, 3, 4, and 5.

Note 4

Step 2.b of the RepeatMatcher states that once the minimum number of repetitions has been satisfied, any more expansions of Atom that match the empty character sequence are not considered for further repetitions. This prevents the regular expression engine from falling into an infinite loop on patterns such as:

/(a*)*/.exec("b")

or the slightly more complicated:

/(a*)b\1+/.exec("baaaac")

which returns the array

["b", ""]

22.2.2.3.2 EmptyMatcher ( )

The abstract operation EmptyMatcher takes no arguments and returns a Matcher. It performs the following steps when called:

  1. Return a new Matcher with parameters (x, c) that captures nothing and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Return c(x).

22.2.2.3.3 MatchTwoAlternatives ( m1, m2 )

The abstract operation MatchTwoAlternatives takes arguments m1 (a Matcher) and m2 (a Matcher) and returns a Matcher. It performs the following steps when called:

  1. Return a new Matcher with parameters (x, c) that captures m1 and m2 and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let r be m1(x, c).
    4. If r is not failure, return r.
    5. Return m2(x, c).

22.2.2.3.4 MatchSequence ( m1, m2, direction )

The abstract operation MatchSequence takes arguments m1 (a Matcher), m2 (a Matcher), and direction (forward or backward) and returns a Matcher. It performs the following steps when called:

  1. If direction is forward, then
    1. Return a new Matcher with parameters (x, c) that captures m1 and m2 and performs the following steps when called:
      1. Assert: x is a MatchState.
      2. Assert: c is a MatcherContinuation.
      3. Let d be a new MatcherContinuation with parameters (y) that captures c and m2 and performs the following steps when called:
        1. Assert: y is a MatchState.
        2. Return m2(y, c).
      4. Return m1(x, d).
  2. Else,
    1. Assert: direction is backward.
    2. Return a new Matcher with parameters (x, c) that captures m1 and m2 and performs the following steps when called:
      1. Assert: x is a MatchState.
      2. Assert: c is a MatcherContinuation.
      3. Let d be a new MatcherContinuation with parameters (y) that captures c and m1 and performs the following steps when called:
        1. Assert: y is a MatchState.
        2. Return m1(y, c).
      4. Return m2(x, d).

22.2.2.4 Runtime Semantics: CompileAssertion

The syntax-directed operation CompileAssertion takes argument rer (a RegExp Record) and returns a Matcher.

Note 1

This section is amended in B.1.2.6.

It is defined piecewise over the following productions:

Assertion :: ^
  1. Return a new Matcher with parameters (x, c) that captures rer and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let e be x.[[EndIndex]].
    5. If e = 0, or if rer.[[Multiline]] is true and the character Input[e - 1] is matched by LineTerminator, then
      1. Return c(x).
    6. Return failure.
Note 2

Even when the y flag is used with a pattern, ^ always matches only at the beginning of Input, or (if rer.[[Multiline]] is true) at the beginning of a line.

Assertion :: $
  1. Return a new Matcher with parameters (x, c) that captures rer and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let e be x.[[EndIndex]].
    5. Let InputLength be the number of elements in Input.
    6. If e = InputLength, or if rer.[[Multiline]] is true and the character Input[e] is matched by LineTerminator, then
      1. Return c(x).
    7. Return failure.
Assertion :: \b
  1. Return a new Matcher with parameters (x, c) that captures rer and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let e be x.[[EndIndex]].
    5. Let a be IsWordChar(rer, Input, e - 1).
    6. Let b be IsWordChar(rer, Input, e).
    7. If a is true and b is false, or if a is false and b is true, return c(x).
    8. Return failure.
Assertion :: \B
  1. Return a new Matcher with parameters (x, c) that captures rer and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let e be x.[[EndIndex]].
    5. Let a be IsWordChar(rer, Input, e - 1).
    6. Let b be IsWordChar(rer, Input, e).
    7. If a is true and b is true, or if a is false and b is false, return c(x).
    8. Return failure.
Assertion :: (?= Disjunction )
  1. Let m be CompileSubpattern of Disjunction with arguments rer and forward.
  2. Return a new Matcher with parameters (x, c) that captures m and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let d be a new MatcherContinuation with parameters (y) that captures nothing and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Return y.
    4. Let r be m(x, d).
    5. If r is failure, return failure.
    6. Assert: r is a MatchState.
    7. Let cap be r.[[Captures]].
    8. Let Input be x.[[Input]].
    9. Let xe be x.[[EndIndex]].
    10. Let z be the MatchState { [[Input]]: Input, [[EndIndex]]: xe, [[Captures]]: cap }.
    11. Return c(z).
Note 3

The form (?= Disjunction ) specifies a zero-width positive lookahead. In order for it to succeed, the pattern inside Disjunction must match at the current position, but the current position is not advanced before matching the sequel. If Disjunction can match at the current position in several ways, only the first one is tried. Unlike other regular expression operators, there is no backtracking into a (?= form (this unusual behaviour is inherited from Perl). This only matters when the Disjunction contains capturing parentheses and the sequel of the pattern contains backreferences to those captures.

For example,

/(?=(a+))/.exec("baaabac")

matches the empty String immediately after the first b and therefore returns the array:

["", "aaa"]

To illustrate the lack of backtracking into the lookahead, consider:

/(?=(a+))a*b\1/.exec("baaabac")

This expression returns

["aba", "a"]

and not:

["aaaba", "a"]
Assertion :: (?! Disjunction )
  1. Let m be CompileSubpattern of Disjunction with arguments rer and forward.
  2. Return a new Matcher with parameters (x, c) that captures m and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let d be a new MatcherContinuation with parameters (y) that captures nothing and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Return y.
    4. Let r be m(x, d).
    5. If r is not failure, return failure.
    6. Return c(x).
Note 4

The form (?! Disjunction ) specifies a zero-width negative lookahead. In order for it to succeed, the pattern inside Disjunction must fail to match at the current position. The current position is not advanced before matching the sequel. Disjunction can contain capturing parentheses, but backreferences to them only make sense from within Disjunction itself. Backreferences to these capturing parentheses from elsewhere in the pattern always return undefined because the negative lookahead must fail for the pattern to succeed. For example,

/(.*?)a(?!(a+)b\2c)\2(.*)/.exec("baaabaac")

looks for an a not immediately followed by some positive number n of a's, a b, another n a's (specified by the first \2) and a c. The second \2 is outside the negative lookahead, so it matches against undefined and therefore always succeeds. The whole expression returns the array:

["baaabaac", "ba", undefined, "abaac"]
Assertion :: (?<= Disjunction )
  1. Let m be CompileSubpattern of Disjunction with arguments rer and backward.
  2. Return a new Matcher with parameters (x, c) that captures m and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let d be a new MatcherContinuation with parameters (y) that captures nothing and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Return y.
    4. Let r be m(x, d).
    5. If r is failure, return failure.
    6. Assert: r is a MatchState.
    7. Let cap be r.[[Captures]].
    8. Let Input be x.[[Input]].
    9. Let xe be x.[[EndIndex]].
    10. Let z be the MatchState { [[Input]]: Input, [[EndIndex]]: xe, [[Captures]]: cap }.
    11. Return c(z).
Assertion :: (?<! Disjunction )
  1. Let m be CompileSubpattern of Disjunction with arguments rer and backward.
  2. Return a new Matcher with parameters (x, c) that captures m and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let d be a new MatcherContinuation with parameters (y) that captures nothing and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Return y.
    4. Let r be m(x, d).
    5. If r is not failure, return failure.
    6. Return c(x).

22.2.2.4.1 IsWordChar ( rer, Input, e )

The abstract operation IsWordChar takes arguments rer (a RegExp Record), Input (a List of characters), and e (an integer) and returns a Boolean. It performs the following steps when called:

  1. Let InputLength be the number of elements in Input.
  2. If e = -1 or e = InputLength, return false.
  3. Let c be the character Input[e].
  4. If WordCharacters(rer) contains c, return true.
  5. Return false.

22.2.2.5 Runtime Semantics: CompileQuantifier

The syntax-directed operation CompileQuantifier takes no arguments and returns a Record with fields [[Min]] (a non-negative integer), [[Max]] (a non-negative integer or +∞), and [[Greedy]] (a Boolean). It is defined piecewise over the following productions:

Quantifier :: QuantifierPrefix
  1. Let qp be CompileQuantifierPrefix of QuantifierPrefix.
  2. Return the Record { [[Min]]: qp.[[Min]], [[Max]]: qp.[[Max]], [[Greedy]]: true }.
Quantifier :: QuantifierPrefix ?
  1. Let qp be CompileQuantifierPrefix of QuantifierPrefix.
  2. Return the Record { [[Min]]: qp.[[Min]], [[Max]]: qp.[[Max]], [[Greedy]]: false }.

22.2.2.6 Runtime Semantics: CompileQuantifierPrefix

The syntax-directed operation CompileQuantifierPrefix takes no arguments and returns a Record with fields [[Min]] (a non-negative integer) and [[Max]] (a non-negative integer or +∞). It is defined piecewise over the following productions:

QuantifierPrefix :: *
  1. Return the Record { [[Min]]: 0, [[Max]]: +∞ }.
QuantifierPrefix :: +
  1. Return the Record { [[Min]]: 1, [[Max]]: +∞ }.
QuantifierPrefix :: ?
  1. Return the Record { [[Min]]: 0, [[Max]]: 1 }.
QuantifierPrefix :: { DecimalDigits }
  1. Let i be the MV of DecimalDigits (see 12.9.3).
  2. Return the Record { [[Min]]: i, [[Max]]: i }.
QuantifierPrefix :: { DecimalDigits ,}
  1. Let i be the MV of DecimalDigits.
  2. Return the Record { [[Min]]: i, [[Max]]: +∞ }.
QuantifierPrefix :: { DecimalDigits , DecimalDigits }
  1. Let i be the MV of the first DecimalDigits.
  2. Let j be the MV of the second DecimalDigits.
  3. Return the Record { [[Min]]: i, [[Max]]: j }.

22.2.2.7 Runtime Semantics: CompileAtom

The syntax-directed operation CompileAtom takes arguments rer (a RegExp Record) and direction (forward or backward) and returns a Matcher.

Note 1

This section is amended in B.1.2.7.

It is defined piecewise over the following productions:

Atom :: PatternCharacter
  1. Let ch be the character matched by PatternCharacter.
  2. Let A be a one-element CharSet containing the character ch.
  3. Return CharacterSetMatcher(rer, A, false, direction).
Atom :: .
  1. Let A be AllCharacters(rer).
  2. If rer.[[DotAll]] is not true, then
    1. Remove from A all characters corresponding to a code point on the right-hand side of the LineTerminator production.
  3. Return CharacterSetMatcher(rer, A, false, direction).
Atom :: CharacterClass
  1. Let cc be CompileCharacterClass of CharacterClass with argument rer.
  2. Let cs be cc.[[CharSet]].
  3. If rer.[[UnicodeSets]] is false, or if every CharSetElement of cs consists of a single character (including if cs is empty), return CharacterSetMatcher(rer, cs, cc.[[Invert]], direction).
  4. Assert: cc.[[Invert]] is false.
  5. Let lm be an empty List of Matchers.
  6. For each CharSetElement s in cs containing more than 1 character, iterating in descending order of length, do
    1. Let cs2 be a one-element CharSet containing the last code point of s.
    2. Let m2 be CharacterSetMatcher(rer, cs2, false, direction).
    3. For each code point c1 in s, iterating backwards from its second-to-last code point, do
      1. Let cs1 be a one-element CharSet containing c1.
      2. Let m1 be CharacterSetMatcher(rer, cs1, false, direction).
      3. Set m2 to MatchSequence(m1, m2, direction).
    4. Append m2 to lm.
  7. Let singles be the CharSet containing every CharSetElement of cs that consists of a single character.
  8. Append CharacterSetMatcher(rer, singles, false, direction) to lm.
  9. If cs contains the empty sequence of characters, append EmptyMatcher() to lm.
  10. Let m2 be the last Matcher in lm.
  11. For each Matcher m1 of lm, iterating backwards from its second-to-last element, do
    1. Set m2 to MatchTwoAlternatives(m1, m2).
  12. Return m2.
Atom :: ( GroupSpecifieropt Disjunction )
  1. Let m be CompileSubpattern of Disjunction with arguments rer and direction.
  2. Let parenIndex be CountLeftCapturingParensBefore(Atom).
  3. Return a new Matcher with parameters (x, c) that captures direction, m, and parenIndex and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let d be a new MatcherContinuation with parameters (y) that captures x, c, direction, and parenIndex and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Let cap be a copy of y.[[Captures]].
      3. Let Input be x.[[Input]].
      4. Let xe be x.[[EndIndex]].
      5. Let ye be y.[[EndIndex]].
      6. If direction is forward, then
        1. Assert: xeye.
        2. Let r be the CaptureRange { [[StartIndex]]: xe, [[EndIndex]]: ye }.
      7. Else,
        1. Assert: direction is backward.
        2. Assert: yexe.
        3. Let r be the CaptureRange { [[StartIndex]]: ye, [[EndIndex]]: xe }.
      8. Set cap[parenIndex + 1] to r.
      9. Let z be the MatchState { [[Input]]: Input, [[EndIndex]]: ye, [[Captures]]: cap }.
      10. Return c(z).
    4. Return m(x, d).
Note 2

Parentheses of the form ( Disjunction ) serve both to group the components of the Disjunction pattern together and to save the result of the match. The result can be used either in a backreference (\ followed by a non-zero decimal number), referenced in a replace String, or returned as part of an array from the regular expression matching Abstract Closure. To inhibit the capturing behaviour of parentheses, use the form (?: Disjunction ) instead.

Atom :: (?: Disjunction )
  1. Return CompileSubpattern of Disjunction with arguments rer and direction.
AtomEscape :: DecimalEscape
  1. Let n be the CapturingGroupNumber of DecimalEscape.
  2. Assert: nrer.[[CapturingGroupsCount]].
  3. Return BackreferenceMatcher(rer, n, direction).
Note 3

An escape sequence of the form \ followed by a non-zero decimal number n matches the result of the nth set of capturing parentheses (22.2.2.1). It is an error if the regular expression has fewer than n capturing parentheses. If the regular expression has n or more capturing parentheses but the nth one is undefined because it has not captured anything, then the backreference always succeeds.

AtomEscape :: CharacterEscape
  1. Let cv be the CharacterValue of CharacterEscape.
  2. Let ch be the character whose character value is cv.
  3. Let A be a one-element CharSet containing the character ch.
  4. Return CharacterSetMatcher(rer, A, false, direction).
AtomEscape :: CharacterClassEscape
  1. Let cs be CompileToCharSet of CharacterClassEscape with argument rer.
  2. If rer.[[UnicodeSets]] is false, or if every CharSetElement of cs consists of a single character (including if cs is empty), return CharacterSetMatcher(rer, cs, false, direction).
  3. Let lm be an empty List of Matchers.
  4. For each CharSetElement s in cs containing more than 1 character, iterating in descending order of length, do
    1. Let cs2 be a one-element CharSet containing the last code point of s.
    2. Let m2 be CharacterSetMatcher(rer, cs2, false, direction).
    3. For each code point c1 in s, iterating backwards from its second-to-last code point, do
      1. Let cs1 be a one-element CharSet containing c1.
      2. Let m1 be CharacterSetMatcher(rer, cs1, false, direction).
      3. Set m2 to MatchSequence(m1, m2, direction).
    4. Append m2 to lm.
  5. Let singles be the CharSet containing every CharSetElement of cs that consists of a single character.
  6. Append CharacterSetMatcher(rer, singles, false, direction) to lm.
  7. If cs contains the empty sequence of characters, append EmptyMatcher() to lm.
  8. Let m2 be the last Matcher in lm.
  9. For each Matcher m1 of lm, iterating backwards from its second-to-last element, do
    1. Set m2 to MatchTwoAlternatives(m1, m2).
  10. Return m2.
AtomEscape :: k GroupName
  1. Let matchingGroupSpecifiers be GroupSpecifiersThatMatch(GroupName).
  2. Assert: matchingGroupSpecifiers contains a single GroupSpecifier.
  3. Let groupSpecifier be the sole element of matchingGroupSpecifiers.
  4. Let parenIndex be CountLeftCapturingParensBefore(groupSpecifier).
  5. Return BackreferenceMatcher(rer, parenIndex, direction).

22.2.2.7.1 CharacterSetMatcher ( rer, A, invert, direction )

The abstract operation CharacterSetMatcher takes arguments rer (a RegExp Record), A (a CharSet), invert (a Boolean), and direction (forward or backward) and returns a Matcher. It performs the following steps when called:

  1. If rer.[[UnicodeSets]] is true, then
    1. Assert: invert is false.
    2. Assert: Every CharSetElement of A consists of a single character.
  2. Return a new Matcher with parameters (x, c) that captures rer, A, invert, and direction and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let e be x.[[EndIndex]].
    5. If direction is forward, let f be e + 1.
    6. Else, let f be e - 1.
    7. Let InputLength be the number of elements in Input.
    8. If f < 0 or f > InputLength, return failure.
    9. Let index be min(e, f).
    10. Let ch be the character Input[index].
    11. Let cc be Canonicalize(rer, ch).
    12. If there exists a CharSetElement in A containing exactly one character a such that Canonicalize(rer, a) is cc, let found be true. Otherwise, let found be false.
    13. If invert is false and found is false, return failure.
    14. If invert is true and found is true, return failure.
    15. Let cap be x.[[Captures]].
    16. Let y be the MatchState { [[Input]]: Input, [[EndIndex]]: f, [[Captures]]: cap }.
    17. Return c(y).

22.2.2.7.2 BackreferenceMatcher ( rer, n, direction )

The abstract operation BackreferenceMatcher takes arguments rer (a RegExp Record), n (a positive integer), and direction (forward or backward) and returns a Matcher. It performs the following steps when called:

  1. Assert: n ≥ 1.
  2. Return a new Matcher with parameters (x, c) that captures rer, n, and direction and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let cap be x.[[Captures]].
    5. Let r be cap[n].
    6. If r is undefined, return c(x).
    7. Let e be x.[[EndIndex]].
    8. Let rs be r.[[StartIndex]].
    9. Let re be r.[[EndIndex]].
    10. Let len be re - rs.
    11. If direction is forward, let f be e + len.
    12. Else, let f be e - len.
    13. Let InputLength be the number of elements in Input.
    14. If f < 0 or f > InputLength, return failure.
    15. Let g be min(e, f).
    16. If there exists an integer i in the interval from 0 (inclusive) to len (exclusive) such that Canonicalize(rer, Input[rs + i]) is not Canonicalize(rer, Input[g + i]), return failure.
    17. Let y be the MatchState { [[Input]]: Input, [[EndIndex]]: f, [[Captures]]: cap }.
    18. Return c(y).

22.2.2.7.3 Canonicalize ( rer, ch )

The abstract operation Canonicalize takes arguments rer (a RegExp Record) and ch (a character) and returns a character. It performs the following steps when called:

  1. If HasEitherUnicodeFlag(rer) is true and rer.[[IgnoreCase]] is true, then
    1. If the file CaseFolding.txt of the Unicode Character Database provides a simple or common case folding mapping for ch, return the result of applying that mapping to ch.
    2. Return ch.
  2. If rer.[[IgnoreCase]] is false, return ch.
  3. Assert: ch is a UTF-16 code unit.
  4. Let cp be the code point whose numeric value is the numeric value of ch.
  5. Let u be the result of toUppercase(« cp »), according to the Unicode Default Case Conversion algorithm.
  6. Let uStr be CodePointsToString(u).
  7. If the length of uStr ≠ 1, return ch.
  8. Let cu be uStr's single code unit element.
  9. If the numeric value of ch ≥ 128 and the numeric value of cu < 128, return ch.
  10. Return cu.
Note

In case-insignificant matches when HasEitherUnicodeFlag(rer) is true, all characters are implicitly case-folded using the simple mapping provided by the Unicode Standard immediately before they are compared. The simple mapping always maps to a single code point, so it does not map, for example, ß (U+00DF LATIN SMALL LETTER SHARP S) to ss or SS. It may however map code points outside the Basic Latin block to code points within it—for example, ſ (U+017F LATIN SMALL LETTER LONG S) case-folds to s (U+0073 LATIN SMALL LETTER S) and (U+212A KELVIN SIGN) case-folds to k (U+006B LATIN SMALL LETTER K). Strings containing those code points are matched by regular expressions such as /[a-z]/ui.

In case-insignificant matches when HasEitherUnicodeFlag(rer) is false, the mapping is based on Unicode Default Case Conversion algorithm toUppercase rather than toCasefold, which results in some subtle differences. For example, (U+2126 OHM SIGN) is mapped by toUppercase to itself but by toCasefold to ω (U+03C9 GREEK SMALL LETTER OMEGA) along with Ω (U+03A9 GREEK CAPITAL LETTER OMEGA), so "\u2126" is matched by /[ω]/ui and /[\u03A9]/ui but not by /[ω]/i or /[\u03A9]/i. Also, no code point outside the Basic Latin block is mapped to a code point within it, so strings such as "\u017F ſ" and "\u212A K" are not matched by /[a-z]/i.

22.2.2.8 Runtime Semantics: CompileCharacterClass

The syntax-directed operation CompileCharacterClass takes argument rer (a RegExp Record) and returns a Record with fields [[CharSet]] (a CharSet) and [[Invert]] (a Boolean). It is defined piecewise over the following productions:

CharacterClass :: [ ClassContents ]
  1. Let A be CompileToCharSet of ClassContents with argument rer.
  2. Return the Record { [[CharSet]]: A, [[Invert]]: false }.
CharacterClass :: [^ ClassContents ]
  1. Let A be CompileToCharSet of ClassContents with argument rer.
  2. If rer.[[UnicodeSets]] is true, then
    1. Return the Record { [[CharSet]]: CharacterComplement(rer, A), [[Invert]]: false }.
  3. Return the Record { [[CharSet]]: A, [[Invert]]: true }.

22.2.2.9 Runtime Semantics: CompileToCharSet

The syntax-directed operation CompileToCharSet takes argument rer (a RegExp Record) and returns a CharSet.

Note 1

This section is amended in B.1.2.8.

It is defined piecewise over the following productions:

ClassContents :: [empty]
  1. Return the empty CharSet.
NonemptyClassRanges :: ClassAtom NonemptyClassRangesNoDash
  1. Let A be CompileToCharSet of ClassAtom with argument rer.
  2. Let B be CompileToCharSet of NonemptyClassRangesNoDash with argument rer.
  3. Return the union of CharSets A and B.
NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents
  1. Let A be CompileToCharSet of the first ClassAtom with argument rer.
  2. Let B be CompileToCharSet of the second ClassAtom with argument rer.
  3. Let C be CompileToCharSet of ClassContents with argument rer.
  4. Let D be CharacterRange(A, B).
  5. Return the union of D and C.
NonemptyClassRangesNoDash :: ClassAtomNoDash NonemptyClassRangesNoDash
  1. Let A be CompileToCharSet of ClassAtomNoDash with argument rer.
  2. Let B be CompileToCharSet of NonemptyClassRangesNoDash with argument rer.
  3. Return the union of CharSets A and B.
NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents
  1. Let A be CompileToCharSet of ClassAtomNoDash with argument rer.
  2. Let B be CompileToCharSet of ClassAtom with argument rer.
  3. Let C be CompileToCharSet of ClassContents with argument rer.
  4. Let D be CharacterRange(A, B).
  5. Return the union of D and C.
Note 2

ClassContents can expand into a single ClassAtom and/or ranges of two ClassAtom separated by dashes. In the latter case the ClassContents includes all characters between the first ClassAtom and the second ClassAtom, inclusive; an error occurs if either ClassAtom does not represent a single character (for example, if one is \w) or if the first ClassAtom's character value is strictly greater than the second ClassAtom's character value.

Note 3

Even if the pattern ignores case, the case of the two ends of a range is significant in determining which characters belong to the range. Thus, for example, the pattern /[E-F]/i matches only the letters E, F, e, and f, while the pattern /[E-f]/i matches all uppercase and lowercase letters in the Unicode Basic Latin block as well as the symbols [, \, ], ^, _, and `.

Note 4

A - character can be treated literally or it can denote a range. It is treated literally if it is the first or last character of ClassContents, the beginning or end limit of a range specification, or immediately follows a range specification.

ClassAtom :: -
  1. Return the CharSet containing the single character - U+002D (HYPHEN-MINUS).
ClassAtomNoDash :: SourceCharacter but not one of \ or ] or -
  1. Return the CharSet containing the character matched by SourceCharacter.
ClassEscape :: b - CharacterEscape
  1. Let cv be the CharacterValue of this ClassEscape.
  2. Let c be the character whose character value is cv.
  3. Return the CharSet containing the single character c.
Note 5

A ClassAtom can use any of the escape sequences that are allowed in the rest of the regular expression except for \b, \B, and backreferences. Inside a CharacterClass, \b means the backspace character, while \B and backreferences raise errors. Using a backreference inside a ClassAtom causes an error.

CharacterClassEscape :: d
  1. Return the ten-element CharSet containing the characters 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9.
CharacterClassEscape :: D
  1. Let S be the CharSet returned by CharacterClassEscape :: d .
  2. Return CharacterComplement(rer, S).
CharacterClassEscape :: s
  1. Return the CharSet containing all characters corresponding to a code point on the right-hand side of the WhiteSpace or LineTerminator productions.
CharacterClassEscape :: S
  1. Let S be the CharSet returned by CharacterClassEscape :: s .
  2. Return CharacterComplement(rer, S).
CharacterClassEscape :: w
  1. Return MaybeSimpleCaseFolding(rer, WordCharacters(rer)).
CharacterClassEscape :: W
  1. Let S be the CharSet returned by CharacterClassEscape :: w .
  2. Return CharacterComplement(rer, S).
CharacterClassEscape :: p{ UnicodePropertyValueExpression }
  1. Return CompileToCharSet of UnicodePropertyValueExpression with argument rer.
CharacterClassEscape :: P{ UnicodePropertyValueExpression }
  1. Let S be CompileToCharSet of UnicodePropertyValueExpression with argument rer.
  2. Assert: S contains only single code points.
  3. Return CharacterComplement(rer, S).
UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue
  1. Let ps be the source text matched by UnicodePropertyName.
  2. Let p be UnicodeMatchProperty(rer, ps).
  3. Assert: p is a Unicode property name or property alias listed in the “Property name and aliases” column of Table 67.
  4. Let vs be the source text matched by UnicodePropertyValue.
  5. Let v be UnicodeMatchPropertyValue(p, vs).
  6. Let A be the CharSet containing all Unicode code points whose character database definition includes the property p with value v.
  7. Return MaybeSimpleCaseFolding(rer, A).
UnicodePropertyValueExpression :: LoneUnicodePropertyNameOrValue
  1. Let s be the source text matched by LoneUnicodePropertyNameOrValue.
  2. If UnicodeMatchPropertyValue(General_Category, s) is a Unicode property value or property value alias for the General_Category (gc) property listed in PropertyValueAliases.txt, then
    1. Return the CharSet containing all Unicode code points whose character database definition includes the property “General_Category” with value s.
  3. Let p be UnicodeMatchProperty(rer, s).
  4. Assert: p is a binary Unicode property or binary property alias listed in the “Property name and aliases” column of Table 68, or a binary Unicode property of strings listed in the “Property name” column of Table 69.
  5. Let A be the CharSet containing all CharSetElements whose character database definition includes the property p with value “True”.
  6. Return MaybeSimpleCaseFolding(rer, A).
ClassUnion :: ClassSetRange ClassUnionopt
  1. Let A be CompileToCharSet of ClassSetRange with argument rer.
  2. If ClassUnion is present, then
    1. Let B be CompileToCharSet of ClassUnion with argument rer.
    2. Return the union of CharSets A and B.
  3. Return A.
ClassUnion :: ClassSetOperand ClassUnionopt
  1. Let A be CompileToCharSet of ClassSetOperand with argument rer.
  2. If ClassUnion is present, then
    1. Let B be CompileToCharSet of ClassUnion with argument rer.
    2. Return the union of CharSets A and B.
  3. Return A.
ClassIntersection :: ClassSetOperand && ClassSetOperand
  1. Let A be CompileToCharSet of the first ClassSetOperand with argument rer.
  2. Let B be CompileToCharSet of the second ClassSetOperand with argument rer.
  3. Return the intersection of CharSets A and B.
ClassIntersection :: ClassIntersection && ClassSetOperand
  1. Let A be CompileToCharSet of the ClassIntersection with argument rer.
  2. Let B be CompileToCharSet of the ClassSetOperand with argument rer.
  3. Return the intersection of CharSets A and B.
ClassSubtraction :: ClassSetOperand -- ClassSetOperand
  1. Let A be CompileToCharSet of the first ClassSetOperand with argument rer.
  2. Let B be CompileToCharSet of the second ClassSetOperand with argument rer.
  3. Return the CharSet containing the CharSetElements of A which are not also CharSetElements of B.
ClassSubtraction :: ClassSubtraction -- ClassSetOperand
  1. Let A be CompileToCharSet of the ClassSubtraction with argument rer.
  2. Let B be CompileToCharSet of the ClassSetOperand with argument rer.
  3. Return the CharSet containing the CharSetElements of A which are not also CharSetElements of B.
ClassSetRange :: ClassSetCharacter - ClassSetCharacter
  1. Let A be CompileToCharSet of the first ClassSetCharacter with argument rer.
  2. Let B be CompileToCharSet of the second ClassSetCharacter with argument rer.
  3. Return MaybeSimpleCaseFolding(rer, CharacterRange(A, B)).
Note 6

The result will often consist of two or more ranges. When UnicodeSets is true and IgnoreCase is true, then MaybeSimpleCaseFolding(rer, [Ā-č]) will include only the odd-numbered code points of that range.

ClassSetOperand :: ClassSetCharacter
  1. Let A be CompileToCharSet of ClassSetCharacter with argument rer.
  2. Return MaybeSimpleCaseFolding(rer, A).
ClassSetOperand :: ClassStringDisjunction
  1. Let A be CompileToCharSet of ClassStringDisjunction with argument rer.
  2. Return MaybeSimpleCaseFolding(rer, A).
ClassSetOperand :: NestedClass
  1. Return CompileToCharSet of NestedClass with argument rer.
NestedClass :: [ ClassContents ]
  1. Return CompileToCharSet of ClassContents with argument rer.
NestedClass :: [^ ClassContents ]
  1. Let A be CompileToCharSet of ClassContents with argument rer.
  2. Return CharacterComplement(rer, A).
NestedClass :: \ CharacterClassEscape
  1. Return CompileToCharSet of CharacterClassEscape with argument rer.
ClassStringDisjunction :: \q{ ClassStringDisjunctionContents }
  1. Return CompileToCharSet of ClassStringDisjunctionContents with argument rer.
ClassStringDisjunctionContents :: ClassString
  1. Let s be CompileClassSetString of ClassString with argument rer.
  2. Return the CharSet containing the one string s.
ClassStringDisjunctionContents :: ClassString | ClassStringDisjunctionContents
  1. Let s be CompileClassSetString of ClassString with argument rer.
  2. Let A be the CharSet containing the one string s.
  3. Let B be CompileToCharSet of ClassStringDisjunctionContents with argument rer.
  4. Return the union of CharSets A and B.
ClassSetCharacter :: SourceCharacter but not ClassSetSyntaxCharacter \ CharacterEscape \ ClassSetReservedPunctuator
  1. Let cv be the CharacterValue of this ClassSetCharacter.
  2. Let c be the character whose character value is cv.
  3. Return the CharSet containing the single character c.
ClassSetCharacter :: \b
  1. Return the CharSet containing the single character U+0008 (BACKSPACE).

22.2.2.9.1 CharacterRange ( A, B )

The abstract operation CharacterRange takes arguments A (a CharSet) and B (a CharSet) and returns a CharSet. It performs the following steps when called:

  1. Assert: A and B each contain exactly one character.
  2. Let a be the one character in CharSet A.
  3. Let b be the one character in CharSet B.
  4. Let i be the character value of character a.
  5. Let j be the character value of character b.
  6. Assert: ij.
  7. Return the CharSet containing all characters with a character value in the inclusive interval from i to j.

22.2.2.9.2 HasEitherUnicodeFlag ( rer )

The abstract operation HasEitherUnicodeFlag takes argument rer (a RegExp Record) and returns a Boolean. It performs the following steps when called:

  1. If rer.[[Unicode]] is true or rer.[[UnicodeSets]] is true, then
    1. Return true.
  2. Return false.

22.2.2.9.3 WordCharacters ( rer )

The abstract operation WordCharacters takes argument rer (a RegExp Record) and returns a CharSet. Returns a CharSet containing the characters considered "word characters" for the purposes of \b, \B, \w, and \W It performs the following steps when called:

  1. Let basicWordChars be the CharSet containing every character in the ASCII word characters.
  2. Let extraWordChars be the CharSet containing all characters c such that c is not in basicWordChars but Canonicalize(rer, c) is in basicWordChars.
  3. Assert: extraWordChars is empty unless HasEitherUnicodeFlag(rer) is true and rer.[[IgnoreCase]] is true.
  4. Return the union of basicWordChars and extraWordChars.

22.2.2.9.4 AllCharacters ( rer )

The abstract operation AllCharacters takes argument rer (a RegExp Record) and returns a CharSet. Returns the set of “all characters” according to the regular expression flags. It performs the following steps when called:

  1. If rer.[[UnicodeSets]] is true and rer.[[IgnoreCase]] is true, then
    1. Return the CharSet containing all Unicode code points c that do not have a Simple Case Folding mapping (that is, scf(c)=c).
  2. Else if HasEitherUnicodeFlag(rer) is true, then
    1. Return the CharSet containing all code point values.
  3. Else,
    1. Return the CharSet containing all code unit values.

22.2.2.9.5 MaybeSimpleCaseFolding ( rer, A )

The abstract operation MaybeSimpleCaseFolding takes arguments rer (a RegExp Record) and A (a CharSet) and returns a CharSet. If rer.[[UnicodeSets]] is false or rer.[[IgnoreCase]] is false, it returns A. Otherwise, it uses the Simple Case Folding (scf(cp)) definitions in the file CaseFolding.txt of the Unicode Character Database (each of which maps a single code point to another single code point) to map each CharSetElement of A character-by-character into a canonical form and returns the resulting CharSet. It performs the following steps when called:

  1. If rer.[[UnicodeSets]] is false or rer.[[IgnoreCase]] is false, return A.
  2. Let B be a new empty CharSet.
  3. For each CharSetElement s of A, do
    1. Let t be an empty sequence of characters.
    2. For each single code point cp in s, do
      1. Append scf(cp) to t.
    3. Add t to B.
  4. Return B.

22.2.2.9.6 CharacterComplement ( rer, S )

The abstract operation CharacterComplement takes arguments rer (a RegExp Record) and S (a CharSet) and returns a CharSet. It performs the following steps when called:

  1. Let A be AllCharacters(rer).
  2. Return the CharSet containing the CharSetElements of A which are not also CharSetElements of S.

22.2.2.9.7 UnicodeMatchProperty ( rer, p )

The abstract operation UnicodeMatchProperty takes arguments rer (a RegExp Record) and p (ECMAScript source text) and returns a Unicode property name. It performs the following steps when called:

  1. If rer.[[UnicodeSets]] is true and p is a Unicode property name listed in the “Property name” column of Table 69, then
    1. Return the List of Unicode code points p.
  2. Assert: p is a Unicode property name or property alias listed in the “Property name and aliases” column of Table 67 or Table 68.
  3. Let c be the canonical property name of p as given in the “Canonical property name” column of the corresponding row.
  4. Return the List of Unicode code points c.

Implementations must support the Unicode property names and aliases listed in Table 67, Table 68, and Table 69. To ensure interoperability, implementations must not support any other property names or aliases.

Note 1

For example, Script_Extensions (property name) and scx (property alias) are valid, but script_extensions or Scx aren't.

Note 2

The listed properties form a superset of what UTS18 RL1.2 requires.

Note 3

The spellings of entries in these tables (including casing) match the spellings used in the file PropertyAliases.txt in the Unicode Character Database. The precise spellings in that file are guaranteed to be stable.

Table 67: Non-binary Unicode property aliases and their canonical property names
Property name and aliases Canonical property name
General_Category General_Category
gc
Script Script
sc
Script_Extensions Script_Extensions
scx
Table 68: Binary Unicode property aliases and their canonical property names
Property name and aliases Canonical property name
ASCII ASCII
ASCII_Hex_Digit ASCII_Hex_Digit
AHex
Alphabetic Alphabetic
Alpha
Any Any
Assigned Assigned
Bidi_Control Bidi_Control
Bidi_C
Bidi_Mirrored Bidi_Mirrored
Bidi_M
Case_Ignorable Case_Ignorable
CI
Cased Cased
Changes_When_Casefolded Changes_When_Casefolded
CWCF
Changes_When_Casemapped Changes_When_Casemapped
CWCM
Changes_When_Lowercased Changes_When_Lowercased
CWL
Changes_When_NFKC_Casefolded Changes_When_NFKC_Casefolded
CWKCF
Changes_When_Titlecased Changes_When_Titlecased
CWT
Changes_When_Uppercased Changes_When_Uppercased
CWU
Dash Dash
Default_Ignorable_Code_Point Default_Ignorable_Code_Point
DI
Deprecated Deprecated
Dep
Diacritic Diacritic
Dia
Emoji Emoji
Emoji_Component Emoji_Component
EComp
Emoji_Modifier Emoji_Modifier
EMod
Emoji_Modifier_Base Emoji_Modifier_Base
EBase
Emoji_Presentation Emoji_Presentation
EPres
Extended_Pictographic Extended_Pictographic
ExtPict
Extender Extender
Ext
Grapheme_Base Grapheme_Base
Gr_Base
Grapheme_Extend Grapheme_Extend
Gr_Ext
Hex_Digit Hex_Digit
Hex
IDS_Binary_Operator IDS_Binary_Operator
IDSB
IDS_Trinary_Operator IDS_Trinary_Operator
IDST
ID_Continue ID_Continue
IDC
ID_Start ID_Start
IDS
Ideographic Ideographic
Ideo
Join_Control Join_Control
Join_C
Logical_Order_Exception Logical_Order_Exception
LOE
Lowercase Lowercase
Lower
Math Math
Noncharacter_Code_Point Noncharacter_Code_Point
NChar
Pattern_Syntax Pattern_Syntax
Pat_Syn
Pattern_White_Space Pattern_White_Space
Pat_WS
Quotation_Mark Quotation_Mark
QMark
Radical Radical
Regional_Indicator Regional_Indicator
RI
Sentence_Terminal Sentence_Terminal
STerm
Soft_Dotted Soft_Dotted
SD
Terminal_Punctuation Terminal_Punctuation
Term
Unified_Ideograph Unified_Ideograph
UIdeo
Uppercase Uppercase
Upper
Variation_Selector Variation_Selector
VS
White_Space White_Space
space
XID_Continue XID_Continue
XIDC
XID_Start XID_Start
XIDS
Table 69: Binary Unicode properties of strings
Property name
Basic_Emoji
Emoji_Keycap_Sequence
RGI_Emoji_Modifier_Sequence
RGI_Emoji_Flag_Sequence
RGI_Emoji_Tag_Sequence
RGI_Emoji_ZWJ_Sequence
RGI_Emoji

22.2.2.9.8 UnicodeMatchPropertyValue ( p, v )

The abstract operation UnicodeMatchPropertyValue takes arguments p (ECMAScript source text) and v (ECMAScript source text) and returns a Unicode property value. It performs the following steps when called:

  1. Assert: p is a canonical, unaliased Unicode property name listed in the “Canonical property name” column of Table 67.
  2. Assert: v is a property value or property value alias for the Unicode property p listed in PropertyValueAliases.txt.
  3. Let value be the canonical property value of v as given in the “Canonical property value” column of the corresponding row.
  4. Return the List of Unicode code points value.

Implementations must support the Unicode property values and property value aliases listed in PropertyValueAliases.txt for the properties listed in Table 67. To ensure interoperability, implementations must not support any other property values or property value aliases.

Note 1

For example, Xpeo and Old_Persian are valid Script_Extensions values, but xpeo and Old Persian aren't.

Note 2

This algorithm differs from the matching rules for symbolic values listed in UAX44: case, white space, U+002D (HYPHEN-MINUS), and U+005F (LOW LINE) are not ignored, and the Is prefix is not supported.

22.2.2.10 Runtime Semantics: CompileClassSetString

The syntax-directed operation CompileClassSetString takes argument rer (a RegExp Record) and returns a sequence of characters. It is defined piecewise over the following productions:

ClassString :: [empty]
  1. Return an empty sequence of characters.
ClassString :: NonEmptyClassString
  1. Return CompileClassSetString of NonEmptyClassString with argument rer.
NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt
  1. Let cs be CompileToCharSet of ClassSetCharacter with argument rer.
  2. Let s1 be the sequence of characters that is the single CharSetElement of cs.
  3. If NonEmptyClassString is present, then
    1. Let s2 be CompileClassSetString of NonEmptyClassString with argument rer.
    2. Return the concatenation of s1 and s2.
  4. Return s1.

22.2.3 Abstract Operations for RegExp Creation

22.2.3.1 RegExpCreate ( P, F )

The abstract operation RegExpCreate takes arguments P (an ECMAScript language value) and F (a String or undefined) and returns either a normal completion containing an Object or a throw completion. It performs the following steps when called:

  1. Let obj be ! RegExpAlloc(%RegExp%).
  2. Return ? RegExpInitialize(obj, P, F).

22.2.3.2 RegExpAlloc ( newTarget )

The abstract operation RegExpAlloc takes argument newTarget (a constructor) and returns either a normal completion containing an Object or a throw completion. It performs the following steps when called:

  1. Let obj be ? OrdinaryCreateFromConstructor(newTarget, "%RegExp.prototype%", « [[OriginalSource]], [[OriginalFlags]], [[RegExpRecord]], [[RegExpMatcher]] »).
  2. Perform ! DefinePropertyOrThrow(obj, "lastIndex", PropertyDescriptor { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  3. Return obj.

22.2.3.3 RegExpInitialize ( obj, pattern, flags )

The abstract operation RegExpInitialize takes arguments obj (an Object), pattern (an ECMAScript language value), and flags (an ECMAScript language value) and returns either a normal completion containing an Object or a throw completion. It performs the following steps when called:

  1. If pattern is undefined, let P be the empty String.
  2. Else, let P be ? ToString(pattern).
  3. If flags is undefined, let F be the empty String.
  4. Else, let F be ? ToString(flags).
  5. If F contains any code unit other than "d", "g", "i", "m", "s", "u", "v", or "y", or if F contains any code unit more than once, throw a SyntaxError exception.
  6. If F contains "i", let i be true; else let i be false.
  7. If F contains "m", let m be true; else let m be false.
  8. If F contains "s", let s be true; else let s be false.
  9. If F contains "u", let u be true; else let u be false.
  10. If F contains "v", let v be true; else let v be false.
  11. If u is true or v is true, then
    1. Let patternText be StringToCodePoints(P).
  12. Else,
    1. Let patternText be the result of interpreting each of P's 16-bit elements as a Unicode BMP code point. UTF-16 decoding is not applied to the elements.
  13. Let parseResult be ParsePattern(patternText, u, v).
  14. If parseResult is a non-empty List of SyntaxError objects, throw a SyntaxError exception.
  15. Assert: parseResult is a Pattern Parse Node.
  16. Set obj.[[OriginalSource]] to P.
  17. Set obj.[[OriginalFlags]] to F.
  18. Let capturingGroupsCount be CountLeftCapturingParensWithin(parseResult).
  19. Let rer be the RegExp Record { [[IgnoreCase]]: i, [[Multiline]]: m, [[DotAll]]: s, [[Unicode]]: u, [[UnicodeSets]]: v, [[CapturingGroupsCount]]: capturingGroupsCount }.
  20. Set obj.[[RegExpRecord]] to rer.
  21. Set obj.[[RegExpMatcher]] to CompilePattern of parseResult with argument rer.
  22. Perform ? Set(obj, "lastIndex", +0𝔽, true).
  23. Return obj.

22.2.3.4 Static Semantics: ParsePattern ( patternText, u, v )

The abstract operation ParsePattern takes arguments patternText (a sequence of Unicode code points), u (a Boolean), and v (a Boolean) and returns a Parse Node or a non-empty List of SyntaxError objects.

Note

This section is amended in B.1.2.9.

It performs the following steps when called:

  1. If v is true and u is true, then
    1. Let parseResult be a List containing one or more SyntaxError objects.
  2. Else if v is true, then
    1. Let parseResult be ParseText(patternText, Pattern[+UnicodeMode, +UnicodeSetsMode, +NamedCaptureGroups]).
  3. Else if u is true, then
    1. Let parseResult be ParseText(patternText, Pattern[+UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups]).
  4. Else,
    1. Let parseResult be ParseText(patternText, Pattern[~UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups]).
  5. Return parseResult.

22.2.4 The RegExp Constructor

The RegExp constructor:

  • is %RegExp%.
  • is the initial value of the "RegExp" property of the global object.
  • creates and initializes a new RegExp object when called as a constructor.
  • when called as a function rather than as a constructor, returns either a new RegExp object, or the argument itself if the only argument is a RegExp object.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified RegExp behaviour must include a super call to the RegExp constructor to create and initialize subclass instances with the necessary internal slots.

22.2.4.1 RegExp ( pattern, flags )

This function performs the following steps when called:

  1. Let patternIsRegExp be ? IsRegExp(pattern).
  2. If NewTarget is undefined, then
    1. Let newTarget be the active function object.
    2. If patternIsRegExp is true and flags is undefined, then
      1. Let patternConstructor be ? Get(pattern, "constructor").
      2. If SameValue(newTarget, patternConstructor) is true, return pattern.
  3. Else,
    1. Let newTarget be NewTarget.
  4. If pattern is an Object and pattern has a [[RegExpMatcher]] internal slot, then
    1. Let P be pattern.[[OriginalSource]].
    2. If flags is undefined, let F be pattern.[[OriginalFlags]].
    3. Else, let F be flags.
  5. Else if patternIsRegExp is true, then
    1. Let P be ? Get(pattern, "source").
    2. If flags is undefined, then
      1. Let F be ? Get(pattern, "flags").
    3. Else,
      1. Let F be flags.
  6. Else,
    1. Let P be pattern.
    2. Let F be flags.
  7. Let O be ? RegExpAlloc(newTarget).
  8. Return ? RegExpInitialize(O, P, F).
Note

If pattern is supplied using a StringLiteral, the usual escape sequence substitutions are performed before the String is processed by this function. If pattern must contain an escape sequence to be recognized by this function, any U+005C (REVERSE SOLIDUS) code points must be escaped within the StringLiteral to prevent them being removed when the contents of the StringLiteral are formed.

22.2.5 Properties of the RegExp Constructor

The RegExp constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

22.2.5.1 RegExp.prototype

The initial value of RegExp.prototype is the RegExp prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

22.2.5.2 get RegExp [ @@species ]

RegExp[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

RegExp prototype methods normally use their this value's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.

22.2.6 Properties of the RegExp Prototype Object

The RegExp prototype object:

  • is %RegExp.prototype%.
  • is an ordinary object.
  • is not a RegExp instance and does not have a [[RegExpMatcher]] internal slot or any of the other internal slots of RegExp instance objects.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
Note

The RegExp prototype object does not have a "valueOf" property of its own; however, it inherits the "valueOf" property from the Object prototype object.

22.2.6.1 RegExp.prototype.constructor

The initial value of RegExp.prototype.constructor is %RegExp%.

22.2.6.2 RegExp.prototype.exec ( string )

This method searches string for an occurrence of the regular expression pattern and returns an Array containing the results of the match, or null if string did not match.

It performs the following steps when called:

  1. Let R be the this value.
  2. Perform ? RequireInternalSlot(R, [[RegExpMatcher]]).
  3. Let S be ? ToString(string).
  4. Return ? RegExpBuiltinExec(R, S).

22.2.6.3 get RegExp.prototype.dotAll

RegExp.prototype.dotAll is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0073 (LATIN SMALL LETTER S).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.4 get RegExp.prototype.flags

RegExp.prototype.flags is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. If R is not an Object, throw a TypeError exception.
  3. Let codeUnits be a new empty List.
  4. Let hasIndices be ToBoolean(? Get(R, "hasIndices")).
  5. If hasIndices is true, append the code unit 0x0064 (LATIN SMALL LETTER D) to codeUnits.
  6. Let global be ToBoolean(? Get(R, "global")).
  7. If global is true, append the code unit 0x0067 (LATIN SMALL LETTER G) to codeUnits.
  8. Let ignoreCase be ToBoolean(? Get(R, "ignoreCase")).
  9. If ignoreCase is true, append the code unit 0x0069 (LATIN SMALL LETTER I) to codeUnits.
  10. Let multiline be ToBoolean(? Get(R, "multiline")).
  11. If multiline is true, append the code unit 0x006D (LATIN SMALL LETTER M) to codeUnits.
  12. Let dotAll be ToBoolean(? Get(R, "dotAll")).
  13. If dotAll is true, append the code unit 0x0073 (LATIN SMALL LETTER S) to codeUnits.
  14. Let unicode be ToBoolean(? Get(R, "unicode")).
  15. If unicode is true, append the code unit 0x0075 (LATIN SMALL LETTER U) to codeUnits.
  16. Let unicodeSets be ToBoolean(? Get(R, "unicodeSets")).
  17. If unicodeSets is true, append the code unit 0x0076 (LATIN SMALL LETTER V) to codeUnits.
  18. Let sticky be ToBoolean(? Get(R, "sticky")).
  19. If sticky is true, append the code unit 0x0079 (LATIN SMALL LETTER Y) to codeUnits.
  20. Return the String value whose code units are the elements of the List codeUnits. If codeUnits has no elements, the empty String is returned.

22.2.6.4.1 RegExpHasFlag ( R, codeUnit )

The abstract operation RegExpHasFlag takes arguments R (an ECMAScript language value) and codeUnit (a code unit) and returns either a normal completion containing either a Boolean or undefined, or a throw completion. It performs the following steps when called:

  1. If R is not an Object, throw a TypeError exception.
  2. If R does not have an [[OriginalFlags]] internal slot, then
    1. If SameValue(R, %RegExp.prototype%) is true, return undefined.
    2. Otherwise, throw a TypeError exception.
  3. Let flags be R.[[OriginalFlags]].
  4. If flags contains codeUnit, return true.
  5. Return false.

22.2.6.5 get RegExp.prototype.global

RegExp.prototype.global is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0067 (LATIN SMALL LETTER G).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.6 get RegExp.prototype.hasIndices

RegExp.prototype.hasIndices is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0064 (LATIN SMALL LETTER D).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.7 get RegExp.prototype.ignoreCase

RegExp.prototype.ignoreCase is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0069 (LATIN SMALL LETTER I).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.8 RegExp.prototype [ @@match ] ( string )

This method performs the following steps when called:

  1. Let rx be the this value.
  2. If rx is not an Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let flags be ? ToString(? Get(rx, "flags")).
  5. If flags does not contain "g", then
    1. Return ? RegExpExec(rx, S).
  6. Else,
    1. If flags contains "u" or flags contains "v", let fullUnicode be true. Otherwise, let fullUnicode be false.
    2. Perform ? Set(rx, "lastIndex", +0𝔽, true).
    3. Let A be ! ArrayCreate(0).
    4. Let n be 0.
    5. Repeat,
      1. Let result be ? RegExpExec(rx, S).
      2. If result is null, then
        1. If n = 0, return null.
        2. Return A.
      3. Else,
        1. Let matchStr be ? ToString(? Get(result, "0")).
        2. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), matchStr).
        3. If matchStr is the empty String, then
          1. Let thisIndex be (? ToLength(? Get(rx, "lastIndex"))).
          2. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode).
          3. Perform ? Set(rx, "lastIndex", 𝔽(nextIndex), true).
        4. Set n to n + 1.

The value of the "name" property of this method is "[Symbol.match]".

Note

The @@match property is used by the IsRegExp abstract operation to identify objects that have the basic behaviour of regular expressions. The absence of a @@match property or the existence of such a property whose value does not Boolean coerce to true indicates that the object is not intended to be used as a regular expression object.

22.2.6.9 RegExp.prototype [ @@matchAll ] ( string )

This method performs the following steps when called:

  1. Let R be the this value.
  2. If R is not an Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let C be ? SpeciesConstructor(R, %RegExp%).
  5. Let flags be ? ToString(? Get(R, "flags")).
  6. Let matcher be ? Construct(C, « R, flags »).
  7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")).
  8. Perform ? Set(matcher, "lastIndex", lastIndex, true).
  9. If flags contains "g", let global be true.
  10. Else, let global be false.
  11. If flags contains "u" or flags contains "v", let fullUnicode be true.
  12. Else, let fullUnicode be false.
  13. Return CreateRegExpStringIterator(matcher, S, global, fullUnicode).

The value of the "name" property of this method is "[Symbol.matchAll]".

22.2.6.10 get RegExp.prototype.multiline

RegExp.prototype.multiline is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x006D (LATIN SMALL LETTER M).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.11 RegExp.prototype [ @@replace ] ( string, replaceValue )

This method performs the following steps when called:

  1. Let rx be the this value.
  2. If rx is not an Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let lengthS be the length of S.
  5. Let functionalReplace be IsCallable(replaceValue).
  6. If functionalReplace is false, then
    1. Set replaceValue to ? ToString(replaceValue).
  7. Let flags be ? ToString(? Get(rx, "flags")).
  8. If flags contains "g", let global be true. Otherwise, let global be false.
  9. If global is true, then
    1. Perform ? Set(rx, "lastIndex", +0𝔽, true).
  10. Let results be a new empty List.
  11. Let done be false.
  12. Repeat, while done is false,
    1. Let result be ? RegExpExec(rx, S).
    2. If result is null, then
      1. Set done to true.
    3. Else,
      1. Append result to results.
      2. If global is false, then
        1. Set done to true.
      3. Else,
        1. Let matchStr be ? ToString(? Get(result, "0")).
        2. If matchStr is the empty String, then
          1. Let thisIndex be (? ToLength(? Get(rx, "lastIndex"))).
          2. If flags contains "u" or flags contains "v", let fullUnicode be true. Otherwise, let fullUnicode be false.
          3. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode).
          4. Perform ? Set(rx, "lastIndex", 𝔽(nextIndex), true).
  13. Let accumulatedResult be the empty String.
  14. Let nextSourcePosition be 0.
  15. For each element result of results, do
    1. Let resultLength be ? LengthOfArrayLike(result).
    2. Let nCaptures be max(resultLength - 1, 0).
    3. Let matched be ? ToString(? Get(result, "0")).
    4. Let matchLength be the length of matched.
    5. Let position be ? ToIntegerOrInfinity(? Get(result, "index")).
    6. Set position to the result of clamping position between 0 and lengthS.
    7. Let captures be a new empty List.
    8. Let n be 1.
    9. Repeat, while nnCaptures,
      1. Let capN be ? Get(result, ! ToString(𝔽(n))).
      2. If capN is not undefined, then
        1. Set capN to ? ToString(capN).
      3. Append capN to captures.
      4. NOTE: When n = 1, the preceding step puts the first element into captures (at index 0). More generally, the nth capture (the characters captured by the nth set of capturing parentheses) is at captures[n - 1].
      5. Set n to n + 1.
    10. Let namedCaptures be ? Get(result, "groups").
    11. If functionalReplace is true, then
      1. Let replacerArgs be the list-concatenation of « matched », captures, and « 𝔽(position), S ».
      2. If namedCaptures is not undefined, then
        1. Append namedCaptures to replacerArgs.
      3. Let replValue be ? Call(replaceValue, undefined, replacerArgs).
      4. Let replacement be ? ToString(replValue).
    12. Else,
      1. If namedCaptures is not undefined, then
        1. Set namedCaptures to ? ToObject(namedCaptures).
      2. Let replacement be ? GetSubstitution(matched, S, position, captures, namedCaptures, replaceValue).
    13. If positionnextSourcePosition, then
      1. NOTE: position should not normally move backwards. If it does, it is an indication of an ill-behaving RegExp subclass or use of an access triggered side-effect to change the global flag or other characteristics of rx. In such cases, the corresponding substitution is ignored.
      2. Set accumulatedResult to the string-concatenation of accumulatedResult, the substring of S from nextSourcePosition to position, and replacement.
      3. Set nextSourcePosition to position + matchLength.
  16. If nextSourcePositionlengthS, return accumulatedResult.
  17. Return the string-concatenation of accumulatedResult and the substring of S from nextSourcePosition.

The value of the "name" property of this method is "[Symbol.replace]".

22.2.6.12 RegExp.prototype [ @@search ] ( string )

This method performs the following steps when called:

  1. Let rx be the this value.
  2. If rx is not an Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let previousLastIndex be ? Get(rx, "lastIndex").
  5. If SameValue(previousLastIndex, +0𝔽) is false, then
    1. Perform ? Set(rx, "lastIndex", +0𝔽, true).
  6. Let result be ? RegExpExec(rx, S).
  7. Let currentLastIndex be ? Get(rx, "lastIndex").
  8. If SameValue(currentLastIndex, previousLastIndex) is false, then
    1. Perform ? Set(rx, "lastIndex", previousLastIndex, true).
  9. If result is null, return -1𝔽.
  10. Return ? Get(result, "index").

The value of the "name" property of this method is "[Symbol.search]".

Note

The "lastIndex" and "global" properties of this RegExp object are ignored when performing the search. The "lastIndex" property is left unchanged.

22.2.6.13 get RegExp.prototype.source

RegExp.prototype.source is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. If R is not an Object, throw a TypeError exception.
  3. If R does not have an [[OriginalSource]] internal slot, then
    1. If SameValue(R, %RegExp.prototype%) is true, return "(?:)".
    2. Otherwise, throw a TypeError exception.
  4. Assert: R has an [[OriginalFlags]] internal slot.
  5. Let src be R.[[OriginalSource]].
  6. Let flags be R.[[OriginalFlags]].
  7. Return EscapeRegExpPattern(src, flags).

22.2.6.13.1 EscapeRegExpPattern ( P, F )

The abstract operation EscapeRegExpPattern takes arguments P (a String) and F (a String) and returns a String. It performs the following steps when called:

  1. If F contains "v", then
    1. Let patternSymbol be Pattern[+UnicodeMode, +UnicodeSetsMode].
  2. Else if F contains "u", then
    1. Let patternSymbol be Pattern[+UnicodeMode, ~UnicodeSetsMode].
  3. Else,
    1. Let patternSymbol be Pattern[~UnicodeMode, ~UnicodeSetsMode].
  4. Let S be a String in the form of a patternSymbol equivalent to P interpreted as UTF-16 encoded Unicode code points (6.1.4), in which certain code points are escaped as described below. S may or may not differ from P; however, the Abstract Closure that would result from evaluating S as a patternSymbol must behave identically to the Abstract Closure given by the constructed object's [[RegExpMatcher]] internal slot. Multiple calls to this abstract operation using the same values for P and F must produce identical results.
  5. The code points / or any LineTerminator occurring in the pattern shall be escaped in S as necessary to ensure that the string-concatenation of "/", S, "/", and F can be parsed (in an appropriate lexical context) as a RegularExpressionLiteral that behaves identically to the constructed regular expression. For example, if P is "/", then S could be "\/" or "\u002F", among other possibilities, but not "/", because /// followed by F would be parsed as a SingleLineComment rather than a RegularExpressionLiteral. If P is the empty String, this specification can be met by letting S be "(?:)".
  6. Return S.

22.2.6.14 RegExp.prototype [ @@split ] ( string, limit )

Note 1

This method returns an Array into which substrings of the result of converting string to a String have been stored. The substrings are determined by searching from left to right for matches of the this value regular expression; these occurrences are not part of any String in the returned array, but serve to divide up the String value.

The this value may be an empty regular expression or a regular expression that can match an empty String. In this case, the regular expression does not match the empty substring at the beginning or end of the input String, nor does it match the empty substring at the end of the previous separator match. (For example, if the regular expression matches the empty String, the String is split up into individual code unit elements; the length of the result array equals the length of the String, and each substring contains one code unit.) Only the first match at a given index of the String is considered, even if backtracking could yield a non-empty substring match at that index. (For example, /a*?/[Symbol.split]("ab") evaluates to the array ["a", "b"], while /a*/[Symbol.split]("ab") evaluates to the array ["","b"].)

If string is (or converts to) the empty String, the result depends on whether the regular expression can match the empty String. If it can, the result array contains no elements. Otherwise, the result array contains one element, which is the empty String.

If the regular expression contains capturing parentheses, then each time separator is matched the results (including any undefined results) of the capturing parentheses are spliced into the output array. For example,

/<(\/)?([^<>]+)>/[Symbol.split]("A<B>bold</B>and<CODE>coded</CODE>")

evaluates to the array

["A", undefined, "B", "bold", "/", "B", "and", undefined, "CODE", "coded", "/", "CODE", ""]

If limit is not undefined, then the output array is truncated so that it contains no more than limit elements.

This method performs the following steps when called:

  1. Let rx be the this value.
  2. If rx is not an Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let C be ? SpeciesConstructor(rx, %RegExp%).
  5. Let flags be ? ToString(? Get(rx, "flags")).
  6. If flags contains "u" or flags contains "v", let unicodeMatching be true.
  7. Else, let unicodeMatching be false.
  8. If flags contains "y", let newFlags be flags.
  9. Else, let newFlags be the string-concatenation of flags and "y".
  10. Let splitter be ? Construct(C, « rx, newFlags »).
  11. Let A be ! ArrayCreate(0).
  12. Let lengthA be 0.
  13. If limit is undefined, let lim be 232 - 1; else let lim be (? ToUint32(limit)).
  14. If lim = 0, return A.
  15. If S is the empty String, then
    1. Let z be ? RegExpExec(splitter, S).
    2. If z is not null, return A.
    3. Perform ! CreateDataPropertyOrThrow(A, "0", S).
    4. Return A.
  16. Let size be the length of S.
  17. Let p be 0.
  18. Let q be p.
  19. Repeat, while q < size,
    1. Perform ? Set(splitter, "lastIndex", 𝔽(q), true).
    2. Let z be ? RegExpExec(splitter, S).
    3. If z is null, then
      1. Set q to AdvanceStringIndex(S, q, unicodeMatching).
    4. Else,
      1. Let e be (? ToLength(? Get(splitter, "lastIndex"))).
      2. Set e to min(e, size).
      3. If e = p, then
        1. Set q to AdvanceStringIndex(S, q, unicodeMatching).
      4. Else,
        1. Let T be the substring of S from p to q.
        2. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(lengthA)), T).
        3. Set lengthA to lengthA + 1.
        4. If lengthA = lim, return A.
        5. Set p to e.
        6. Let numberOfCaptures be ? LengthOfArrayLike(z).
        7. Set numberOfCaptures to max(numberOfCaptures - 1, 0).
        8. Let i be 1.
        9. Repeat, while inumberOfCaptures,
          1. Let nextCapture be ? Get(z, ! ToString(𝔽(i))).
          2. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(lengthA)), nextCapture).
          3. Set i to i + 1.
          4. Set lengthA to lengthA + 1.
          5. If lengthA = lim, return A.
        10. Set q to p.
  20. Let T be the substring of S from p to size.
  21. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(lengthA)), T).
  22. Return A.

The value of the "name" property of this method is "[Symbol.split]".

Note 2

This method ignores the value of the "global" and "sticky" properties of this RegExp object.

22.2.6.15 get RegExp.prototype.sticky

RegExp.prototype.sticky is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0079 (LATIN SMALL LETTER Y).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.16 RegExp.prototype.test ( S )

This method performs the following steps when called:

  1. Let R be the this value.
  2. If R is not an Object, throw a TypeError exception.
  3. Let string be ? ToString(S).
  4. Let match be ? RegExpExec(R, string).
  5. If match is not null, return true; else return false.

22.2.6.17 RegExp.prototype.toString ( )

  1. Let R be the this value.
  2. If R is not an Object, throw a TypeError exception.
  3. Let pattern be ? ToString(? Get(R, "source")).
  4. Let flags be ? ToString(? Get(R, "flags")).
  5. Let result be the string-concatenation of "/", pattern, "/", and flags.
  6. Return result.
Note

The returned String has the form of a RegularExpressionLiteral that evaluates to another RegExp object with the same behaviour as this object.

22.2.6.18 get RegExp.prototype.unicode

RegExp.prototype.unicode is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0075 (LATIN SMALL LETTER U).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.19 get RegExp.prototype.unicodeSets

RegExp.prototype.unicodeSets is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0076 (LATIN SMALL LETTER V).
  3. Return ? RegExpHasFlag(R, cu).

22.2.7 Abstract Operations for RegExp Matching

22.2.7.1 RegExpExec ( R, S )

The abstract operation RegExpExec takes arguments R (an Object) and S (a String) and returns either a normal completion containing either an Object or null, or a throw completion. It performs the following steps when called:

  1. Let exec be ? Get(R, "exec").
  2. If IsCallable(exec) is true, then
    1. Let result be ? Call(exec, R, « S »).
    2. If result is not an Object and result is not null, throw a TypeError exception.
    3. Return result.
  3. Perform ? RequireInternalSlot(R, [[RegExpMatcher]]).
  4. Return ? RegExpBuiltinExec(R, S).
Note

If a callable "exec" property is not found this algorithm falls back to attempting to use the built-in RegExp matching algorithm. This provides compatible behaviour for code written for prior editions where most built-in algorithms that use regular expressions did not perform a dynamic property lookup of "exec".

22.2.7.2 RegExpBuiltinExec ( R, S )

The abstract operation RegExpBuiltinExec takes arguments R (an initialized RegExp instance) and S (a String) and returns either a normal completion containing either an Array exotic object or null, or a throw completion. It performs the following steps when called:

  1. Let length be the length of S.
  2. Let lastIndex be (? ToLength(? Get(R, "lastIndex"))).
  3. Let flags be R.[[OriginalFlags]].
  4. If flags contains "g", let global be true; else let global be false.
  5. If flags contains "y", let sticky be true; else let sticky be false.
  6. If flags contains "d", let hasIndices be true; else let hasIndices be false.
  7. If global is false and sticky is false, set lastIndex to 0.
  8. Let matcher be R.[[RegExpMatcher]].
  9. If flags contains "u" or flags contains "v", let fullUnicode be true; else let fullUnicode be false.
  10. Let matchSucceeded be false.
  11. If fullUnicode is true, let input be StringToCodePoints(S). Otherwise, let input be a List whose elements are the code units that are the elements of S.
  12. NOTE: Each element of input is considered to be a character.
  13. Repeat, while matchSucceeded is false,
    1. If lastIndex > length, then
      1. If global is true or sticky is true, then
        1. Perform ? Set(R, "lastIndex", +0𝔽, true).
      2. Return null.
    2. Let inputIndex be the index into input of the character that was obtained from element lastIndex of S.
    3. Let r be matcher(input, inputIndex).
    4. If r is failure, then
      1. If sticky is true, then
        1. Perform ? Set(R, "lastIndex", +0𝔽, true).
        2. Return null.
      2. Set lastIndex to AdvanceStringIndex(S, lastIndex, fullUnicode).
    5. Else,
      1. Assert: r is a MatchState.
      2. Set matchSucceeded to true.
  14. Let e be r.[[EndIndex]].
  15. If fullUnicode is true, set e to GetStringIndex(S, e).
  16. If global is true or sticky is true, then
    1. Perform ? Set(R, "lastIndex", 𝔽(e), true).
  17. Let n be the number of elements in r.[[Captures]].
  18. Assert: n = R.[[RegExpRecord]].[[CapturingGroupsCount]].
  19. Assert: n < 232 - 1.
  20. Let A be ! ArrayCreate(n + 1).
  21. Assert: The mathematical value of A's "length" property is n + 1.
  22. Perform ! CreateDataPropertyOrThrow(A, "index", 𝔽(lastIndex)).
  23. Perform ! CreateDataPropertyOrThrow(A, "input", S).
  24. Let match be the Match Record { [[StartIndex]]: lastIndex, [[EndIndex]]: e }.
  25. Let indices be a new empty List.
  26. Let groupNames be a new empty List.
  27. Append match to indices.
  28. Let matchedSubstr be GetMatchString(S, match).
  29. Perform ! CreateDataPropertyOrThrow(A, "0", matchedSubstr).
  30. If R contains any GroupName, then
    1. Let groups be OrdinaryObjectCreate(null).
    2. Let hasGroups be true.
  31. Else,
    1. Let groups be undefined.
    2. Let hasGroups be false.
  32. Perform ! CreateDataPropertyOrThrow(A, "groups", groups).
  33. For each integer i such that 1 ≤ in, in ascending order, do
    1. Let captureI be ith element of r.[[Captures]].
    2. If captureI is undefined, then
      1. Let capturedValue be undefined.
      2. Append undefined to indices.
    3. Else,
      1. Let captureStart be captureI.[[StartIndex]].
      2. Let captureEnd be captureI.[[EndIndex]].
      3. If fullUnicode is true, then
        1. Set captureStart to GetStringIndex(S, captureStart).
        2. Set captureEnd to GetStringIndex(S, captureEnd).
      4. Let capture be the Match Record { [[StartIndex]]: captureStart, [[EndIndex]]: captureEnd }.
      5. Let capturedValue be GetMatchString(S, capture).
      6. Append capture to indices.
    4. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(i)), capturedValue).
    5. If the ith capture of R was defined with a GroupName, then
      1. Let s be the CapturingGroupName of that GroupName.
      2. Perform ! CreateDataPropertyOrThrow(groups, s, capturedValue).
      3. Append s to groupNames.
    6. Else,
      1. Append undefined to groupNames.
  34. If hasIndices is true, then
    1. Let indicesArray be MakeMatchIndicesIndexPairArray(S, indices, groupNames, hasGroups).
    2. Perform ! CreateDataPropertyOrThrow(A, "indices", indicesArray).
  35. Return A.

22.2.7.3 AdvanceStringIndex ( S, index, unicode )

The abstract operation AdvanceStringIndex takes arguments S (a String), index (a non-negative integer), and unicode (a Boolean) and returns an integer. It performs the following steps when called:

  1. Assert: index ≤ 253 - 1.
  2. If unicode is false, return index + 1.
  3. Let length be the length of S.
  4. If index + 1 ≥ length, return index + 1.
  5. Let cp be CodePointAt(S, index).
  6. Return index + cp.[[CodeUnitCount]].

22.2.7.4 GetStringIndex ( S, codePointIndex )

The abstract operation GetStringIndex takes arguments S (a String) and codePointIndex (a non-negative integer) and returns a non-negative integer. It interprets S as a sequence of UTF-16 encoded code points, as described in 6.1.4, and returns the code unit index corresponding to code point index codePointIndex when such an index exists. Otherwise, it returns the length of S. It performs the following steps when called:

  1. If S is the empty String, return 0.
  2. Let len be the length of S.
  3. Let codeUnitCount be 0.
  4. Let codePointCount be 0.
  5. Repeat, while codeUnitCount < len,
    1. If codePointCount = codePointIndex, return codeUnitCount.
    2. Let cp be CodePointAt(S, codeUnitCount).
    3. Set codeUnitCount to codeUnitCount + cp.[[CodeUnitCount]].
    4. Set codePointCount to codePointCount + 1.
  6. Return len.

22.2.7.5 Match Records

A Match Record is a Record value used to encapsulate the start and end indices of a regular expression match or capture.

Match Records have the fields listed in Table 70.

Table 70: Match Record Fields
Field Name Value Meaning
[[StartIndex]] a non-negative integer The number of code units from the start of a string at which the match begins (inclusive).
[[EndIndex]] an integer[[StartIndex]] The number of code units from the start of a string at which the match ends (exclusive).

22.2.7.6 GetMatchString ( S, match )

The abstract operation GetMatchString takes arguments S (a String) and match (a Match Record) and returns a String. It performs the following steps when called:

  1. Assert: match.[[StartIndex]]match.[[EndIndex]] ≤ the length of S.
  2. Return the substring of S from match.[[StartIndex]] to match.[[EndIndex]].

22.2.7.7 GetMatchIndexPair ( S, match )

The abstract operation GetMatchIndexPair takes arguments S (a String) and match (a Match Record) and returns an Array. It performs the following steps when called:

  1. Assert: match.[[StartIndex]]match.[[EndIndex]] ≤ the length of S.
  2. Return CreateArrayFromList𝔽(match.[[StartIndex]]), 𝔽(match.[[EndIndex]]) »).

22.2.7.8 MakeMatchIndicesIndexPairArray ( S, indices, groupNames, hasGroups )

The abstract operation MakeMatchIndicesIndexPairArray takes arguments S (a String), indices (a List of either Match Records or undefined), groupNames (a List of either Strings or undefined), and hasGroups (a Boolean) and returns an Array. It performs the following steps when called:

  1. Let n be the number of elements in indices.
  2. Assert: n < 232 - 1.
  3. Assert: groupNames has n - 1 elements.
  4. NOTE: The groupNames List contains elements aligned with the indices List starting at indices[1].
  5. Let A be ! ArrayCreate(n).
  6. If hasGroups is true, then
    1. Let groups be OrdinaryObjectCreate(null).
  7. Else,
    1. Let groups be undefined.
  8. Perform ! CreateDataPropertyOrThrow(A, "groups", groups).
  9. For each integer i such that 0 ≤ i < n, in ascending order, do
    1. Let matchIndices be indices[i].
    2. If matchIndices is not undefined, then
      1. Let matchIndexPair be GetMatchIndexPair(S, matchIndices).
    3. Else,
      1. Let matchIndexPair be undefined.
    4. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(i)), matchIndexPair).
    5. If i > 0 and groupNames[i - 1] is not undefined, then
      1. Assert: groups is not undefined.
      2. Perform ! CreateDataPropertyOrThrow(groups, groupNames[i - 1], matchIndexPair).
  10. Return A.

22.2.8 Properties of RegExp Instances

RegExp instances are ordinary objects that inherit properties from the RegExp prototype object. RegExp instances have internal slots [[OriginalSource]], [[OriginalFlags]], [[RegExpRecord]], and [[RegExpMatcher]]. The value of the [[RegExpMatcher]] internal slot is an Abstract Closure representation of the Pattern of the RegExp object.

Note

Prior to ECMAScript 2015, RegExp instances were specified as having the own data properties "source", "global", "ignoreCase", and "multiline". Those properties are now specified as accessor properties of RegExp.prototype.

RegExp instances also have the following property:

22.2.8.1 lastIndex

The value of the "lastIndex" property specifies the String index at which to start the next match. It is coerced to an integral Number when used (see 22.2.7.2). This property shall have the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

22.2.9 RegExp String Iterator Objects

A RegExp String Iterator is an object, that represents a specific iteration over some specific String instance object, matching against some specific RegExp instance object. There is not a named constructor for RegExp String Iterator objects. Instead, RegExp String Iterator objects are created by calling certain methods of RegExp instance objects.

22.2.9.1 CreateRegExpStringIterator ( R, S, global, fullUnicode )

The abstract operation CreateRegExpStringIterator takes arguments R (an Object), S (a String), global (a Boolean), and fullUnicode (a Boolean) and returns a Generator. It performs the following steps when called:

  1. Let closure be a new Abstract Closure with no parameters that captures R, S, global, and fullUnicode and performs the following steps when called:
    1. Repeat,
      1. Let match be ? RegExpExec(R, S).
      2. If match is null, return undefined.
      3. If global is false, then
        1. Perform ? GeneratorYield(CreateIterResultObject(match, false)).
        2. Return undefined.
      4. Let matchStr be ? ToString(? Get(match, "0")).
      5. If matchStr is the empty String, then
        1. Let thisIndex be (? ToLength(? Get(R, "lastIndex"))).
        2. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode).
        3. Perform ? Set(R, "lastIndex", 𝔽(nextIndex), true).
      6. Perform ? GeneratorYield(CreateIterResultObject(match, false)).
  2. Return CreateIteratorFromClosure(closure, "%RegExpStringIteratorPrototype%", %RegExpStringIteratorPrototype%).

22.2.9.2 The %RegExpStringIteratorPrototype% Object

The %RegExpStringIteratorPrototype% object:

  • has properties that are inherited by all RegExp String Iterator Objects.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %IteratorPrototype%.
  • has the following properties:

22.2.9.2.1 %RegExpStringIteratorPrototype%.next ( )

  1. Return ? GeneratorResume(this value, empty, "%RegExpStringIteratorPrototype%").

22.2.9.2.2 %RegExpStringIteratorPrototype% [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "RegExp String Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

23 Indexed Collections

23.1 Array Objects

Arrays are exotic objects that give special treatment to a certain class of property names. See 10.4.2 for a definition of this special treatment.

23.1.1 The Array Constructor

The Array constructor:

  • is %Array%.
  • is the initial value of the "Array" property of the global object.
  • creates and initializes a new Array when called as a constructor.
  • also creates and initializes a new Array when called as a function rather than as a constructor. Thus the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments.
  • is a function whose behaviour differs based upon the number and types of its arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the exotic Array behaviour must include a super call to the Array constructor to initialize subclass instances that are Array exotic objects. However, most of the Array.prototype methods are generic methods that are not dependent upon their this value being an Array exotic object.

23.1.1.1 Array ( ...values )

This function performs the following steps when called:

  1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
  2. Let proto be ? GetPrototypeFromConstructor(newTarget, "%Array.prototype%").
  3. Let numberOfArgs be the number of elements in values.
  4. If numberOfArgs = 0, then
    1. Return ! ArrayCreate(0, proto).
  5. Else if numberOfArgs = 1, then
    1. Let len be values[0].
    2. Let array be ! ArrayCreate(0, proto).
    3. If len is not a Number, then
      1. Perform ! CreateDataPropertyOrThrow(array, "0", len).
      2. Let intLen be 1𝔽.
    4. Else,
      1. Let intLen be ! ToUint32(len).
      2. If SameValueZero(intLen, len) is false, throw a RangeError exception.
    5. Perform ! Set(array, "length", intLen, true).
    6. Return array.
  6. Else,
    1. Assert: numberOfArgs ≥ 2.
    2. Let array be ? ArrayCreate(numberOfArgs, proto).
    3. Let k be 0.
    4. Repeat, while k < numberOfArgs,
      1. Let Pk be ! ToString(𝔽(k)).
      2. Let itemK be values[k].
      3. Perform ! CreateDataPropertyOrThrow(array, Pk, itemK).
      4. Set k to k + 1.
    5. Assert: The mathematical value of array's "length" property is numberOfArgs.
    6. Return array.

23.1.2 Properties of the Array Constructor

The Array constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has a "length" property whose value is 1𝔽.
  • has the following properties:

23.1.2.1 Array.from ( items [ , mapfn [ , thisArg ] ] )

This method performs the following steps when called:

  1. Let C be the this value.
  2. If mapfn is undefined, then
    1. Let mapping be false.
  3. Else,
    1. If IsCallable(mapfn) is false, throw a TypeError exception.
    2. Let mapping be true.
  4. Let usingIterator be ? GetMethod(items, @@iterator).
  5. If usingIterator is not undefined, then
    1. If IsConstructor(C) is true, then
      1. Let A be ? Construct(C).
    2. Else,
      1. Let A be ! ArrayCreate(0).
    3. Let iteratorRecord be ? GetIteratorFromMethod(items, usingIterator).
    4. Let k be 0.
    5. Repeat,
      1. If k ≥ 253 - 1, then
        1. Let error be ThrowCompletion(a newly created TypeError object).
        2. Return ? IteratorClose(iteratorRecord, error).
      2. Let Pk be ! ToString(𝔽(k)).
      3. Let next be ? IteratorStepValue(iteratorRecord).
      4. If next is done, then
        1. Perform ? Set(A, "length", 𝔽(k), true).
        2. Return A.
      5. If mapping is true, then
        1. Let mappedValue be Completion(Call(mapfn, thisArg, « next, 𝔽(k) »)).
        2. IfAbruptCloseIterator(mappedValue, iteratorRecord).
      6. Else,
        1. Let mappedValue be next.
      7. Let defineStatus be Completion(CreateDataPropertyOrThrow(A, Pk, mappedValue)).
      8. IfAbruptCloseIterator(defineStatus, iteratorRecord).
      9. Set k to k + 1.
  6. NOTE: items is not an Iterable so assume it is an array-like object.
  7. Let arrayLike be ! ToObject(items).
  8. Let len be ? LengthOfArrayLike(arrayLike).
  9. If IsConstructor(C) is true, then
    1. Let A be ? Construct(C, « 𝔽(len) »).
  10. Else,
    1. Let A be ? ArrayCreate(len).
  11. Let k be 0.
  12. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ? Get(arrayLike, Pk).
    3. If mapping is true, then
      1. Let mappedValue be ? Call(mapfn, thisArg, « kValue, 𝔽(k) »).
    4. Else,
      1. Let mappedValue be kValue.
    5. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
    6. Set k to k + 1.
  13. Perform ? Set(A, "length", 𝔽(len), true).
  14. Return A.
Note

This method is an intentionally generic factory method; it does not require that its this value be the Array constructor. Therefore it can be transferred to or inherited by any other constructors that may be called with a single numeric argument.

23.1.2.2 Array.isArray ( arg )

This function performs the following steps when called:

  1. Return ? IsArray(arg).

23.1.2.3 Array.of ( ...items )

This method performs the following steps when called:

  1. Let len be the number of elements in items.
  2. Let lenNumber be 𝔽(len).
  3. Let C be the this value.
  4. If IsConstructor(C) is true, then
    1. Let A be ? Construct(C, « lenNumber »).
  5. Else,
    1. Let A be ? ArrayCreate(len).
  6. Let k be 0.
  7. Repeat, while k < len,
    1. Let kValue be items[k].
    2. Let Pk be ! ToString(𝔽(k)).
    3. Perform ? CreateDataPropertyOrThrow(A, Pk, kValue).
    4. Set k to k + 1.
  8. Perform ? Set(A, "length", lenNumber, true).
  9. Return A.
Note

This method is an intentionally generic factory method; it does not require that its this value be the Array constructor. Therefore it can be transferred to or inherited by other constructors that may be called with a single numeric argument.

23.1.2.4 Array.prototype

The value of Array.prototype is the Array prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.1.2.5 get Array [ @@species ]

Array[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

Array prototype methods normally use their this value's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.

23.1.3 Properties of the Array Prototype Object

The Array prototype object:

  • is %Array.prototype%.
  • is an Array exotic object and has the internal methods specified for such objects.
  • has a "length" property whose initial value is +0𝔽 and whose attributes are { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
Note

The Array prototype object is specified to be an Array exotic object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.

23.1.3.1 Array.prototype.at ( index )

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeIndex be ? ToIntegerOrInfinity(index).
  4. If relativeIndex ≥ 0, then
    1. Let k be relativeIndex.
  5. Else,
    1. Let k be len + relativeIndex.
  6. If k < 0 or klen, return undefined.
  7. Return ? Get(O, ! ToString(𝔽(k))).

23.1.3.2 Array.prototype.concat ( ...items )

This method returns an array containing the array elements of the object followed by the array elements of each argument.

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let A be ? ArraySpeciesCreate(O, 0).
  3. Let n be 0.
  4. Prepend O to items.
  5. For each element E of items, do
    1. Let spreadable be ? IsConcatSpreadable(E).
    2. If spreadable is true, then
      1. Let len be ? LengthOfArrayLike(E).
      2. If n + len > 253 - 1, throw a TypeError exception.
      3. Let k be 0.
      4. Repeat, while k < len,
        1. Let Pk be ! ToString(𝔽(k)).
        2. Let exists be ? HasProperty(E, Pk).
        3. If exists is true, then
          1. Let subElement be ? Get(E, Pk).
          2. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), subElement).
        4. Set n to n + 1.
        5. Set k to k + 1.
    3. Else,
      1. NOTE: E is added as a single item rather than spread.
      2. If n ≥ 253 - 1, throw a TypeError exception.
      3. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), E).
      4. Set n to n + 1.
  6. Perform ? Set(A, "length", 𝔽(n), true).
  7. Return A.

The "length" property of this method is 1𝔽.

Note 1

The explicit setting of the "length" property in step 6 is intended to ensure the length is correct when the final non-empty element of items has trailing holes or when A is not a built-in Array.

Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.2.1 IsConcatSpreadable ( O )

The abstract operation IsConcatSpreadable takes argument O (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. If O is not an Object, return false.
  2. Let spreadable be ? Get(O, @@isConcatSpreadable).
  3. If spreadable is not undefined, return ToBoolean(spreadable).
  4. Return ? IsArray(O).

23.1.3.3 Array.prototype.constructor

The initial value of Array.prototype.constructor is %Array%.

23.1.3.4 Array.prototype.copyWithin ( target, start [ , end ] )

Note 1

The end argument is optional. If it is not provided, the length of the this value is used.

Note 2

If target is negative, it is treated as length + target where length is the length of the array. If start is negative, it is treated as length + start. If end is negative, it is treated as length + end.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeTarget be ? ToIntegerOrInfinity(target).
  4. If relativeTarget = -∞, let to be 0.
  5. Else if relativeTarget < 0, let to be max(len + relativeTarget, 0).
  6. Else, let to be min(relativeTarget, len).
  7. Let relativeStart be ? ToIntegerOrInfinity(start).
  8. If relativeStart = -∞, let from be 0.
  9. Else if relativeStart < 0, let from be max(len + relativeStart, 0).
  10. Else, let from be min(relativeStart, len).
  11. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  12. If relativeEnd = -∞, let final be 0.
  13. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
  14. Else, let final be min(relativeEnd, len).
  15. Let count be min(final - from, len - to).
  16. If from < to and to < from + count, then
    1. Let direction be -1.
    2. Set from to from + count - 1.
    3. Set to to to + count - 1.
  17. Else,
    1. Let direction be 1.
  18. Repeat, while count > 0,
    1. Let fromKey be ! ToString(𝔽(from)).
    2. Let toKey be ! ToString(𝔽(to)).
    3. Let fromPresent be ? HasProperty(O, fromKey).
    4. If fromPresent is true, then
      1. Let fromVal be ? Get(O, fromKey).
      2. Perform ? Set(O, toKey, fromVal, true).
    5. Else,
      1. Assert: fromPresent is false.
      2. Perform ? DeletePropertyOrThrow(O, toKey).
    6. Set from to from + direction.
    7. Set to to to + direction.
    8. Set count to count - 1.
  19. Return O.
Note 3

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.5 Array.prototype.entries ( )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Return CreateArrayIterator(O, key+value).

23.1.3.6 Array.prototype.every ( callbackfn [ , thisArg ] )

Note 1

callbackfn should be a function that accepts three arguments and returns a value that is coercible to a Boolean value. every calls callbackfn once for each element present in the array, in ascending order, until it finds one where callbackfn returns false. If such an element is found, every immediately returns false. Otherwise, if callbackfn returned true for all elements, every will return true. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the object being traversed.

every does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by every is set before the first call to callbackfn. Elements which are appended to the array after the call to every begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time every visits them; elements that are deleted after the call to every begins and before being visited are not visited. every acts like the "for all" quantifier in mathematics. In particular, for an empty array, it returns true.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. Let k be 0.
  5. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let testResult be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
      3. If testResult is false, return false.
    4. Set k to k + 1.
  6. Return true.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.7 Array.prototype.fill ( value [ , start [ , end ] ] )

Note 1

The start argument is optional. If it is not provided, +0𝔽 is used.

The end argument is optional. If it is not provided, the length of the this value is used.

Note 2

If start is negative, it is treated as length + start where length is the length of the array. If end is negative, it is treated as length + end.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeStart be ? ToIntegerOrInfinity(start).
  4. If relativeStart = -∞, let k be 0.
  5. Else if relativeStart < 0, let k be max(len + relativeStart, 0).
  6. Else, let k be min(relativeStart, len).
  7. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  8. If relativeEnd = -∞, let final be 0.
  9. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
  10. Else, let final be min(relativeEnd, len).
  11. Repeat, while k < final,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Perform ? Set(O, Pk, value, true).
    3. Set k to k + 1.
  12. Return O.
Note 3

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.8 Array.prototype.filter ( callbackfn [ , thisArg ] )

Note 1

callbackfn should be a function that accepts three arguments and returns a value that is coercible to a Boolean value. filter calls callbackfn once for each element in the array, in ascending order, and constructs a new array of all the values for which callbackfn returns true. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the object being traversed.

filter does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by filter is set before the first call to callbackfn. Elements which are appended to the array after the call to filter begins will not be visited by callbackfn. If existing elements of the array are changed their value as passed to callbackfn will be the value at the time filter visits them; elements that are deleted after the call to filter begins and before being visited are not visited.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. Let A be ? ArraySpeciesCreate(O, 0).
  5. Let k be 0.
  6. Let to be 0.
  7. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let selected be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
      3. If selected is true, then
        1. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(to)), kValue).
        2. Set to to to + 1.
    4. Set k to k + 1.
  8. Return A.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.9 Array.prototype.find ( predicate [ , thisArg ] )

Note 1

This method calls predicate once for each element of the array, in ascending index order, until it finds one where predicate returns a value that coerces to true. If such an element is found, find immediately returns that element value. Otherwise, find returns undefined.

See FindViaPredicate for additional information.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let findRec be ? FindViaPredicate(O, len, ascending, predicate, thisArg).
  4. Return findRec.[[Value]].
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.10 Array.prototype.findIndex ( predicate [ , thisArg ] )

Note 1

This method calls predicate once for each element of the array, in ascending index order, until it finds one where predicate returns a value that coerces to true. If such an element is found, findIndex immediately returns the index of that element value. Otherwise, findIndex returns -1.

See FindViaPredicate for additional information.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let findRec be ? FindViaPredicate(O, len, ascending, predicate, thisArg).
  4. Return findRec.[[Index]].
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.11 Array.prototype.findLast ( predicate [ , thisArg ] )

Note 1

This method calls predicate once for each element of the array, in descending index order, until it finds one where predicate returns a value that coerces to true. If such an element is found, findLast immediately returns that element value. Otherwise, findLast returns undefined.

See FindViaPredicate for additional information.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let findRec be ? FindViaPredicate(O, len, descending, predicate, thisArg).
  4. Return findRec.[[Value]].
Note 2

This method is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.12 Array.prototype.findLastIndex ( predicate [ , thisArg ] )

Note 1

This method calls predicate once for each element of the array, in descending index order, until it finds one where predicate returns a value that coerces to true. If such an element is found, findLastIndex immediately returns the index of that element value. Otherwise, findLastIndex returns -1.

See FindViaPredicate for additional information.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let findRec be ? FindViaPredicate(O, len, descending, predicate, thisArg).
  4. Return findRec.[[Index]].
Note 2

This method is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.12.1 FindViaPredicate ( O, len, direction, predicate, thisArg )

The abstract operation FindViaPredicate takes arguments O (an Object), len (a non-negative integer), direction (ascending or descending), predicate (an ECMAScript language value), and thisArg (an ECMAScript language value) and returns either a normal completion containing a Record with fields [[Index]] (an integral Number) and [[Value]] (an ECMAScript language value) or a throw completion.

O should be an array-like object or a TypedArray. This operation calls predicate once for each element of O, in either ascending index order or descending index order (as indicated by direction), until it finds one where predicate returns a value that coerces to true. At that point, this operation returns a Record that gives the index and value of the element found. If no such element is found, this operation returns a Record that specifies -1𝔽 for the index and undefined for the value.

predicate should be a function. When called for an element of the array, it is passed three arguments: the value of the element, the index of the element, and the object being traversed. Its return value will be coerced to a Boolean value.

thisArg will be used as the this value for each invocation of predicate.

This operation does not directly mutate the object on which it is called, but the object may be mutated by the calls to predicate.

The range of elements processed is set before the first call to predicate, just before the traversal begins. Elements that are appended to the array after this will not be visited by predicate. If existing elements of the array are changed, their value as passed to predicate will be the value at the time that this operation visits them. Elements that are deleted after traversal begins and before being visited are still visited and are either looked up from the prototype or are undefined.

It performs the following steps when called:

  1. If IsCallable(predicate) is false, throw a TypeError exception.
  2. If direction is ascending, then
    1. Let indices be a List of the integers in the interval from 0 (inclusive) to len (exclusive), in ascending order.
  3. Else,
    1. Let indices be a List of the integers in the interval from 0 (inclusive) to len (exclusive), in descending order.
  4. For each integer k of indices, do
    1. Let Pk be ! ToString(𝔽(k)).
    2. NOTE: If O is a TypedArray, the following invocation of Get will return a normal completion.
    3. Let kValue be ? Get(O, Pk).
    4. Let testResult be ? Call(predicate, thisArg, « kValue, 𝔽(k), O »).
    5. If ToBoolean(testResult) is true, return the Record { [[Index]]: 𝔽(k), [[Value]]: kValue }.
  5. Return the Record { [[Index]]: -1𝔽, [[Value]]: undefined }.

23.1.3.13 Array.prototype.flat ( [ depth ] )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let sourceLen be ? LengthOfArrayLike(O).
  3. Let depthNum be 1.
  4. If depth is not undefined, then
    1. Set depthNum to ? ToIntegerOrInfinity(depth).
    2. If depthNum < 0, set depthNum to 0.
  5. Let A be ? ArraySpeciesCreate(O, 0).
  6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, depthNum).
  7. Return A.

23.1.3.13.1 FlattenIntoArray ( target, source, sourceLen, start, depth [ , mapperFunction [ , thisArg ] ] )

The abstract operation FlattenIntoArray takes arguments target (an Object), source (an Object), sourceLen (a non-negative integer), start (a non-negative integer), and depth (a non-negative integer or +∞) and optional arguments mapperFunction (a function object) and thisArg (an ECMAScript language value) and returns either a normal completion containing a non-negative integer or a throw completion. It performs the following steps when called:

  1. Assert: If mapperFunction is present, then IsCallable(mapperFunction) is true, thisArg is present, and depth is 1.
  2. Let targetIndex be start.
  3. Let sourceIndex be +0𝔽.
  4. Repeat, while (sourceIndex) < sourceLen,
    1. Let P be ! ToString(sourceIndex).
    2. Let exists be ? HasProperty(source, P).
    3. If exists is true, then
      1. Let element be ? Get(source, P).
      2. If mapperFunction is present, then
        1. Set element to ? Call(mapperFunction, thisArg, « element, sourceIndex, source »).
      3. Let shouldFlatten be false.
      4. If depth > 0, then
        1. Set shouldFlatten to ? IsArray(element).
      5. If shouldFlatten is true, then
        1. If depth = +∞, let newDepth be +∞.
        2. Else, let newDepth be depth - 1.
        3. Let elementLen be ? LengthOfArrayLike(element).
        4. Set targetIndex to ? FlattenIntoArray(target, element, elementLen, targetIndex, newDepth).
      6. Else,
        1. If targetIndex ≥ 253 - 1, throw a TypeError exception.
        2. Perform ? CreateDataPropertyOrThrow(target, ! ToString(𝔽(targetIndex)), element).
        3. Set targetIndex to targetIndex + 1.
    4. Set sourceIndex to sourceIndex + 1𝔽.
  5. Return targetIndex.

23.1.3.14 Array.prototype.flatMap ( mapperFunction [ , thisArg ] )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let sourceLen be ? LengthOfArrayLike(O).
  3. If IsCallable(mapperFunction) is false, throw a TypeError exception.
  4. Let A be ? ArraySpeciesCreate(O, 0).
  5. Perform ? FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, thisArg).
  6. Return A.

23.1.3.15 Array.prototype.forEach ( callbackfn [ , thisArg ] )

Note 1

callbackfn should be a function that accepts three arguments. forEach calls callbackfn once for each element present in the array, in ascending order. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the object being traversed.

forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by forEach is set before the first call to callbackfn. Elements which are appended to the array after the call to forEach begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time forEach visits them; elements that are deleted after the call to forEach begins and before being visited are not visited.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. Let k be 0.
  5. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Perform ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
    4. Set k to k + 1.
  6. Return undefined.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.16 Array.prototype.includes ( searchElement [ , fromIndex ] )

Note 1

This method compares searchElement to the elements of the array, in ascending order, using the SameValueZero algorithm, and if found at any position, returns true; otherwise, it returns false.

The optional second argument fromIndex defaults to +0𝔽 (i.e. the whole array is searched). If it is greater than or equal to the length of the array, false is returned, i.e. the array will not be searched. If it is less than -0𝔽, it is used as the offset from the end of the array to compute fromIndex. If the computed index is less than or equal to +0𝔽, the whole array will be searched.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If len = 0, return false.
  4. Let n be ? ToIntegerOrInfinity(fromIndex).
  5. Assert: If fromIndex is undefined, then n is 0.
  6. If n = +∞, return false.
  7. Else if n = -∞, set n to 0.
  8. If n ≥ 0, then
    1. Let k be n.
  9. Else,
    1. Let k be len + n.
    2. If k < 0, set k to 0.
  10. Repeat, while k < len,
    1. Let elementK be ? Get(O, ! ToString(𝔽(k))).
    2. If SameValueZero(searchElement, elementK) is true, return true.
    3. Set k to k + 1.
  11. Return false.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

Note 3

This method intentionally differs from the similar indexOf method in two ways. First, it uses the SameValueZero algorithm, instead of IsStrictlyEqual, allowing it to detect NaN array elements. Second, it does not skip missing array elements, instead treating them as undefined.

23.1.3.17 Array.prototype.indexOf ( searchElement [ , fromIndex ] )

This method compares searchElement to the elements of the array, in ascending order, using the IsStrictlyEqual algorithm, and if found at one or more indices, returns the smallest such index; otherwise, it returns -1𝔽.

Note 1

The optional second argument fromIndex defaults to +0𝔽 (i.e. the whole array is searched). If it is greater than or equal to the length of the array, -1𝔽 is returned, i.e. the array will not be searched. If it is less than -0𝔽, it is used as the offset from the end of the array to compute fromIndex. If the computed index is less than or equal to +0𝔽, the whole array will be searched.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If len = 0, return -1𝔽.
  4. Let n be ? ToIntegerOrInfinity(fromIndex).
  5. Assert: If fromIndex is undefined, then n is 0.
  6. If n = +∞, return -1𝔽.
  7. Else if n = -∞, set n to 0.
  8. If n ≥ 0, then
    1. Let k be n.
  9. Else,
    1. Let k be len + n.
    2. If k < 0, set k to 0.
  10. Repeat, while k < len,
    1. Let kPresent be ? HasProperty(O, ! ToString(𝔽(k))).
    2. If kPresent is true, then
      1. Let elementK be ? Get(O, ! ToString(𝔽(k))).
      2. If IsStrictlyEqual(searchElement, elementK) is true, return 𝔽(k).
    3. Set k to k + 1.
  11. Return -1𝔽.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.18 Array.prototype.join ( separator )

This method converts the elements of the array to Strings, and then concatenates these Strings, separated by occurrences of the separator. If no separator is provided, a single comma is used as the separator.

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If separator is undefined, let sep be ",".
  4. Else, let sep be ? ToString(separator).
  5. Let R be the empty String.
  6. Let k be 0.
  7. Repeat, while k < len,
    1. If k > 0, set R to the string-concatenation of R and sep.
    2. Let element be ? Get(O, ! ToString(𝔽(k))).
    3. If element is either undefined or null, let next be the empty String; otherwise, let next be ? ToString(element).
    4. Set R to the string-concatenation of R and next.
    5. Set k to k + 1.
  8. Return R.
Note

This method is intentionally generic; it does not require that its this value be an Array. Therefore, it can be transferred to other kinds of objects for use as a method.

23.1.3.19 Array.prototype.keys ( )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Return CreateArrayIterator(O, key).

23.1.3.20 Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] )

Note 1

This method compares searchElement to the elements of the array in descending order using the IsStrictlyEqual algorithm, and if found at one or more indices, returns the largest such index; otherwise, it returns -1𝔽.

The optional second argument fromIndex defaults to the array's length minus one (i.e. the whole array is searched). If it is greater than or equal to the length of the array, the whole array will be searched. If it is less than -0𝔽, it is used as the offset from the end of the array to compute fromIndex. If the computed index is less than or equal to +0𝔽, -1𝔽 is returned.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If len = 0, return -1𝔽.
  4. If fromIndex is present, let n be ? ToIntegerOrInfinity(fromIndex); else let n be len - 1.
  5. If n = -∞, return -1𝔽.
  6. If n ≥ 0, then
    1. Let k be min(n, len - 1).
  7. Else,
    1. Let k be len + n.
  8. Repeat, while k ≥ 0,
    1. Let kPresent be ? HasProperty(O, ! ToString(𝔽(k))).
    2. If kPresent is true, then
      1. Let elementK be ? Get(O, ! ToString(𝔽(k))).
      2. If IsStrictlyEqual(searchElement, elementK) is true, return 𝔽(k).
    3. Set k to k - 1.
  9. Return -1𝔽.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.21 Array.prototype.map ( callbackfn [ , thisArg ] )

Note 1

callbackfn should be a function that accepts three arguments. map calls callbackfn once for each element in the array, in ascending order, and constructs a new Array from the results. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the object being traversed.

map does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by map is set before the first call to callbackfn. Elements which are appended to the array after the call to map begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time map visits them; elements that are deleted after the call to map begins and before being visited are not visited.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. Let A be ? ArraySpeciesCreate(O, len).
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let mappedValue be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
      3. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
    4. Set k to k + 1.
  7. Return A.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.22 Array.prototype.pop ( )

Note 1

This method removes the last element of the array and returns it.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If len = 0, then
    1. Perform ? Set(O, "length", +0𝔽, true).
    2. Return undefined.
  4. Else,
    1. Assert: len > 0.
    2. Let newLen be 𝔽(len - 1).
    3. Let index be ! ToString(newLen).
    4. Let element be ? Get(O, index).
    5. Perform ? DeletePropertyOrThrow(O, index).
    6. Perform ? Set(O, "length", newLen, true).
    7. Return element.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.23 Array.prototype.push ( ...items )

Note 1

This method appends the arguments to the end of the array, in the order in which they appear. It returns the new length of the array.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let argCount be the number of elements in items.
  4. If len + argCount > 253 - 1, throw a TypeError exception.
  5. For each element E of items, do
    1. Perform ? Set(O, ! ToString(𝔽(len)), E, true).
    2. Set len to len + 1.
  6. Perform ? Set(O, "length", 𝔽(len), true).
  7. Return 𝔽(len).

The "length" property of this method is 1𝔽.

Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.24 Array.prototype.reduce ( callbackfn [ , initialValue ] )

Note 1

callbackfn should be a function that takes four arguments. reduce calls the callback, as a function, once for each element after the first element present in the array, in ascending order.

callbackfn is called with four arguments: the previousValue (value from the previous call to callbackfn), the currentValue (value of the current element), the currentIndex, and the object being traversed. The first time that callback is called, the previousValue and currentValue can be one of two values. If an initialValue was supplied in the call to reduce, then previousValue will be initialValue and currentValue will be the first value in the array. If no initialValue was supplied, then previousValue will be the first value in the array and currentValue will be the second. It is a TypeError if the array contains no elements and initialValue is not provided.

reduce does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by reduce is set before the first call to callbackfn. Elements that are appended to the array after the call to reduce begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time reduce visits them; elements that are deleted after the call to reduce begins and before being visited are not visited.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. If len = 0 and initialValue is not present, throw a TypeError exception.
  5. Let k be 0.
  6. Let accumulator be undefined.
  7. If initialValue is present, then
    1. Set accumulator to initialValue.
  8. Else,
    1. Let kPresent be false.
    2. Repeat, while kPresent is false and k < len,
      1. Let Pk be ! ToString(𝔽(k)).
      2. Set kPresent to ? HasProperty(O, Pk).
      3. If kPresent is true, then
        1. Set accumulator to ? Get(O, Pk).
      4. Set k to k + 1.
    3. If kPresent is false, throw a TypeError exception.
  9. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »).
    4. Set k to k + 1.
  10. Return accumulator.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.25 Array.prototype.reduceRight ( callbackfn [ , initialValue ] )

Note 1

callbackfn should be a function that takes four arguments. reduceRight calls the callback, as a function, once for each element after the first element present in the array, in descending order.

callbackfn is called with four arguments: the previousValue (value from the previous call to callbackfn), the currentValue (value of the current element), the currentIndex, and the object being traversed. The first time the function is called, the previousValue and currentValue can be one of two values. If an initialValue was supplied in the call to reduceRight, then previousValue will be initialValue and currentValue will be the last value in the array. If no initialValue was supplied, then previousValue will be the last value in the array and currentValue will be the second-to-last value. It is a TypeError if the array contains no elements and initialValue is not provided.

reduceRight does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by reduceRight is set before the first call to callbackfn. Elements that are appended to the array after the call to reduceRight begins will not be visited by callbackfn. If existing elements of the array are changed by callbackfn, their value as passed to callbackfn will be the value at the time reduceRight visits them; elements that are deleted after the call to reduceRight begins and before being visited are not visited.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. If len = 0 and initialValue is not present, throw a TypeError exception.
  5. Let k be len - 1.
  6. Let accumulator be undefined.
  7. If initialValue is present, then
    1. Set accumulator to initialValue.
  8. Else,
    1. Let kPresent be false.
    2. Repeat, while kPresent is false and k ≥ 0,
      1. Let Pk be ! ToString(𝔽(k)).
      2. Set kPresent to ? HasProperty(O, Pk).
      3. If kPresent is true, then
        1. Set accumulator to ? Get(O, Pk).
      4. Set k to k - 1.
    3. If kPresent is false, throw a TypeError exception.
  9. Repeat, while k ≥ 0,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »).
    4. Set k to k - 1.
  10. Return accumulator.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.26 Array.prototype.reverse ( )

Note 1

This method rearranges the elements of the array so as to reverse their order. It returns the object as the result of the call.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let middle be floor(len / 2).
  4. Let lower be 0.
  5. Repeat, while lowermiddle,
    1. Let upper be len - lower - 1.
    2. Let upperP be ! ToString(𝔽(upper)).
    3. Let lowerP be ! ToString(𝔽(lower)).
    4. Let lowerExists be ? HasProperty(O, lowerP).
    5. If lowerExists is true, then
      1. Let lowerValue be ? Get(O, lowerP).
    6. Let upperExists be ? HasProperty(O, upperP).
    7. If upperExists is true, then
      1. Let upperValue be ? Get(O, upperP).
    8. If lowerExists is true and upperExists is true, then
      1. Perform ? Set(O, lowerP, upperValue, true).
      2. Perform ? Set(O, upperP, lowerValue, true).
    9. Else if lowerExists is false and upperExists is true, then
      1. Perform ? Set(O, lowerP, upperValue, true).
      2. Perform ? DeletePropertyOrThrow(O, upperP).
    10. Else if lowerExists is true and upperExists is false, then
      1. Perform ? DeletePropertyOrThrow(O, lowerP).
      2. Perform ? Set(O, upperP, lowerValue, true).
    11. Else,
      1. Assert: lowerExists and upperExists are both false.
      2. NOTE: No action is required.
    12. Set lower to lower + 1.
  6. Return O.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore, it can be transferred to other kinds of objects for use as a method.

23.1.3.27 Array.prototype.shift ( )

This method removes the first element of the array and returns it.

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If len = 0, then
    1. Perform ? Set(O, "length", +0𝔽, true).
    2. Return undefined.
  4. Let first be ? Get(O, "0").
  5. Let k be 1.
  6. Repeat, while k < len,
    1. Let from be ! ToString(𝔽(k)).
    2. Let to be ! ToString(𝔽(k - 1)).
    3. Let fromPresent be ? HasProperty(O, from).
    4. If fromPresent is true, then
      1. Let fromVal be ? Get(O, from).
      2. Perform ? Set(O, to, fromVal, true).
    5. Else,
      1. Assert: fromPresent is false.
      2. Perform ? DeletePropertyOrThrow(O, to).
    6. Set k to k + 1.
  7. Perform ? DeletePropertyOrThrow(O, ! ToString(𝔽(len - 1))).
  8. Perform ? Set(O, "length", 𝔽(len - 1), true).
  9. Return first.
Note

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.28 Array.prototype.slice ( start, end )

This method returns an array containing the elements of the array from element start up to, but not including, element end (or through the end of the array if end is undefined). If start is negative, it is treated as length + start where length is the length of the array. If end is negative, it is treated as length + end where length is the length of the array.

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeStart be ? ToIntegerOrInfinity(start).
  4. If relativeStart = -∞, let k be 0.
  5. Else if relativeStart < 0, let k be max(len + relativeStart, 0).
  6. Else, let k be min(relativeStart, len).
  7. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  8. If relativeEnd = -∞, let final be 0.
  9. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
  10. Else, let final be min(relativeEnd, len).
  11. Let count be max(final - k, 0).
  12. Let A be ? ArraySpeciesCreate(O, count).
  13. Let n be 0.
  14. Repeat, while k < final,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), kValue).
    4. Set k to k + 1.
    5. Set n to n + 1.
  15. Perform ? Set(A, "length", 𝔽(n), true).
  16. Return A.
Note 1

The explicit setting of the "length" property in step 15 is intended to ensure the length is correct even when A is not a built-in Array.

Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.29 Array.prototype.some ( callbackfn [ , thisArg ] )

Note 1

callbackfn should be a function that accepts three arguments and returns a value that is coercible to a Boolean value. some calls callbackfn once for each element present in the array, in ascending order, until it finds one where callbackfn returns true. If such an element is found, some immediately returns true. Otherwise, some returns false. callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the element, the index of the element, and the object being traversed.

some does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

The range of elements processed by some is set before the first call to callbackfn. Elements that are appended to the array after the call to some begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time that some visits them; elements that are deleted after the call to some begins and before being visited are not visited. some acts like the "exists" quantifier in mathematics. In particular, for an empty array, it returns false.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. Let k be 0.
  5. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let testResult be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
      3. If testResult is true, return true.
    4. Set k to k + 1.
  6. Return false.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.30 Array.prototype.sort ( comparefn )

This method sorts the elements of this array. The sort must be stable (that is, elements that compare equal must remain in their original order). If comparefn is not undefined, it should be a function that accepts two arguments x and y and returns a negative Number if x < y, a positive Number if x > y, or a zero otherwise.

It performs the following steps when called:

  1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
  2. Let obj be ? ToObject(this value).
  3. Let len be ? LengthOfArrayLike(obj).
  4. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparefn and performs the following steps when called:
    1. Return ? CompareArrayElements(x, y, comparefn).
  5. Let sortedList be ? SortIndexedProperties(obj, len, SortCompare, skip-holes).
  6. Let itemCount be the number of elements in sortedList.
  7. Let j be 0.
  8. Repeat, while j < itemCount,
    1. Perform ? Set(obj, ! ToString(𝔽(j)), sortedList[j], true).
    2. Set j to j + 1.
  9. NOTE: The call to SortIndexedProperties in step 5 uses skip-holes. The remaining indices are deleted to preserve the number of holes that were detected and excluded from the sort.
  10. Repeat, while j < len,
    1. Perform ? DeletePropertyOrThrow(obj, ! ToString(𝔽(j))).
    2. Set j to j + 1.
  11. Return obj.
Note 1

Because non-existent property values always compare greater than undefined property values, and undefined always compares greater than any other value (see CompareArrayElements), undefined property values always sort to the end of the result, followed by non-existent property values.

Note 2

Method calls performed by the ToString abstract operations in steps 5 and 6 have the potential to cause SortCompare to not behave as a consistent comparator.

Note 3

This method is intentionally generic; it does not require that its this value be an Array. Therefore, it can be transferred to other kinds of objects for use as a method.

23.1.3.30.1 SortIndexedProperties ( obj, len, SortCompare, holes )

The abstract operation SortIndexedProperties takes arguments obj (an Object), len (a non-negative integer), SortCompare (an Abstract Closure with two parameters), and holes (skip-holes or read-through-holes) and returns either a normal completion containing a List of ECMAScript language values or a throw completion. It performs the following steps when called:

  1. Let items be a new empty List.
  2. Let k be 0.
  3. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. If holes is skip-holes, then
      1. Let kRead be ? HasProperty(obj, Pk).
    3. Else,
      1. Assert: holes is read-through-holes.
      2. Let kRead be true.
    4. If kRead is true, then
      1. Let kValue be ? Get(obj, Pk).
      2. Append kValue to items.
    5. Set k to k + 1.
  4. Sort items using an implementation-defined sequence of calls to SortCompare. If any such call returns an abrupt completion, stop before performing any further calls to SortCompare and return that Completion Record.
  5. Return items.

The sort order is the ordering of items after completion of step 4 of the algorithm above. The sort order is implementation-defined if SortCompare is not a consistent comparator for the elements of items. When SortIndexedProperties is invoked by Array.prototype.sort, the sort order is also implementation-defined if comparefn is undefined, and all applications of ToString, to any specific value passed as an argument to SortCompare, do not produce the same result.

Unless the sort order is specified to be implementation-defined, it must satisfy all of the following conditions:

  • There must be some mathematical permutation π of the non-negative integers less than itemCount, such that for every non-negative integer j less than itemCount, the element old[j] is exactly the same as new[π(j)].
  • Then for all non-negative integers j and k, each less than itemCount, if (SortCompare(old[j], old[k])) < 0, then π(j) < π(k).

Here the notation old[j] is used to refer to items[j] before step 4 is executed, and the notation new[j] to refer to items[j] after step 4 has been executed.

An abstract closure or function comparator is a consistent comparator for a set of values S if all of the requirements below are met for all values a, b, and c (possibly the same value) in the set S: The notation a <C b means (comparator(a, b)) < 0; a =C b means (comparator(a, b)) = 0; and a >C b means (comparator(a, b)) > 0.

  • Calling comparator(a, b) always returns the same value v when given a specific pair of values a and b as its two arguments. Furthermore, v is a Number, and v is not NaN. Note that this implies that exactly one of a <C b, a =C b, and a >C b will be true for a given pair of a and b.
  • Calling comparator(a, b) does not modify obj or any object on obj's prototype chain.
  • a =C a (reflexivity)
  • If a =C b, then b =C a (symmetry)
  • If a =C b and b =C c, then a =C c (transitivity of =C)
  • If a <C b and b <C c, then a <C c (transitivity of <C)
  • If a >C b and b >C c, then a >C c (transitivity of >C)
Note

The above conditions are necessary and sufficient to ensure that comparator divides the set S into equivalence classes and that these equivalence classes are totally ordered.

23.1.3.30.2 CompareArrayElements ( x, y, comparefn )

The abstract operation CompareArrayElements takes arguments x (an ECMAScript language value), y (an ECMAScript language value), and comparefn (a function object or undefined) and returns either a normal completion containing a Number or an abrupt completion. It performs the following steps when called:

  1. If x and y are both undefined, return +0𝔽.
  2. If x is undefined, return 1𝔽.
  3. If y is undefined, return -1𝔽.
  4. If comparefn is not undefined, then
    1. Let v be ? ToNumber(? Call(comparefn, undefined, « x, y »)).
    2. If v is NaN, return +0𝔽.
    3. Return v.
  5. Let xString be ? ToString(x).
  6. Let yString be ? ToString(y).
  7. Let xSmaller be ! IsLessThan(xString, yString, true).
  8. If xSmaller is true, return -1𝔽.
  9. Let ySmaller be ! IsLessThan(yString, xString, true).
  10. If ySmaller is true, return 1𝔽.
  11. Return +0𝔽.

23.1.3.31 Array.prototype.splice ( start, deleteCount, ...items )

Note 1

This method deletes the deleteCount elements of the array starting at integer index start and replaces them with the elements of items. It returns an Array containing the deleted elements (if any).

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeStart be ? ToIntegerOrInfinity(start).
  4. If relativeStart = -∞, let actualStart be 0.
  5. Else if relativeStart < 0, let actualStart be max(len + relativeStart, 0).
  6. Else, let actualStart be min(relativeStart, len).
  7. Let itemCount be the number of elements in items.
  8. If start is not present, then
    1. Let actualDeleteCount be 0.
  9. Else if deleteCount is not present, then
    1. Let actualDeleteCount be len - actualStart.
  10. Else,
    1. Let dc be ? ToIntegerOrInfinity(deleteCount).
    2. Let actualDeleteCount be the result of clamping dc between 0 and len - actualStart.
  11. If len + itemCount - actualDeleteCount > 253 - 1, throw a TypeError exception.
  12. Let A be ? ArraySpeciesCreate(O, actualDeleteCount).
  13. Let k be 0.
  14. Repeat, while k < actualDeleteCount,
    1. Let from be ! ToString(𝔽(actualStart + k)).
    2. If ? HasProperty(O, from) is true, then
      1. Let fromValue be ? Get(O, from).
      2. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(k)), fromValue).
    3. Set k to k + 1.
  15. Perform ? Set(A, "length", 𝔽(actualDeleteCount), true).
  16. If itemCount < actualDeleteCount, then
    1. Set k to actualStart.
    2. Repeat, while k < (len - actualDeleteCount),
      1. Let from be ! ToString(𝔽(k + actualDeleteCount)).
      2. Let to be ! ToString(𝔽(k + itemCount)).
      3. If ? HasProperty(O, from) is true, then
        1. Let fromValue be ? Get(O, from).
        2. Perform ? Set(O, to, fromValue, true).
      4. Else,
        1. Perform ? DeletePropertyOrThrow(O, to).
      5. Set k to k + 1.
    3. Set k to len.
    4. Repeat, while k > (len - actualDeleteCount + itemCount),
      1. Perform ? DeletePropertyOrThrow(O, ! ToString(𝔽(k - 1))).
      2. Set k to k - 1.
  17. Else if itemCount > actualDeleteCount, then
    1. Set k to (len - actualDeleteCount).
    2. Repeat, while k > actualStart,
      1. Let from be ! ToString(𝔽(k + actualDeleteCount - 1)).
      2. Let to be ! ToString(𝔽(k + itemCount - 1)).
      3. If ? HasProperty(O, from) is true, then
        1. Let fromValue be ? Get(O, from).
        2. Perform ? Set(O, to, fromValue, true).
      4. Else,
        1. Perform ? DeletePropertyOrThrow(O, to).
      5. Set k to k - 1.
  18. Set k to actualStart.
  19. For each element E of items, do
    1. Perform ? Set(O, ! ToString(𝔽(k)), E, true).
    2. Set k to k + 1.
  20. Perform ? Set(O, "length", 𝔽(len - actualDeleteCount + itemCount), true).
  21. Return A.
Note 2

The explicit setting of the "length" property in steps 15 and 20 is intended to ensure the lengths are correct even when the objects are not built-in Arrays.

Note 3

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.32 Array.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used.

Note 1

The first edition of ECMA-402 did not include a replacement specification for this method.

The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

This method performs the following steps when called:

  1. Let array be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(array).
  3. Let separator be the implementation-defined list-separator String value appropriate for the host environment's current locale (such as ", ").
  4. Let R be the empty String.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. If k > 0, then
      1. Set R to the string-concatenation of R and separator.
    2. Let nextElement be ? Get(array, ! ToString(𝔽(k))).
    3. If nextElement is neither undefined nor null, then
      1. Let S be ? ToString(? Invoke(nextElement, "toLocaleString")).
      2. Set R to the string-concatenation of R and S.
    4. Set k to k + 1.
  7. Return R.
Note 2

This method converts the elements of the array to Strings using their toLocaleString methods, and then concatenates these Strings, separated by occurrences of an implementation-defined locale-sensitive separator String. This method is analogous to toString except that it is intended to yield a locale-sensitive result corresponding with conventions of the host environment's current locale.

Note 3

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.33 Array.prototype.toReversed ( )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let A be ? ArrayCreate(len).
  4. Let k be 0.
  5. Repeat, while k < len,
    1. Let from be ! ToString(𝔽(len - k - 1)).
    2. Let Pk be ! ToString(𝔽(k)).
    3. Let fromValue be ? Get(O, from).
    4. Perform ! CreateDataPropertyOrThrow(A, Pk, fromValue).
    5. Set k to k + 1.
  6. Return A.

23.1.3.34 Array.prototype.toSorted ( comparefn )

This method performs the following steps when called:

  1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
  2. Let O be ? ToObject(this value).
  3. Let len be ? LengthOfArrayLike(O).
  4. Let A be ? ArrayCreate(len).
  5. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparefn and performs the following steps when called:
    1. Return ? CompareArrayElements(x, y, comparefn).
  6. Let sortedList be ? SortIndexedProperties(O, len, SortCompare, read-through-holes).
  7. Let j be 0.
  8. Repeat, while j < len,
    1. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(j)), sortedList[j]).
    2. Set j to j + 1.
  9. Return A.

23.1.3.35 Array.prototype.toSpliced ( start, skipCount, ...items )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeStart be ? ToIntegerOrInfinity(start).
  4. If relativeStart is -∞, let actualStart be 0.
  5. Else if relativeStart < 0, let actualStart be max(len + relativeStart, 0).
  6. Else, let actualStart be min(relativeStart, len).
  7. Let insertCount be the number of elements in items.
  8. If start is not present, then
    1. Let actualSkipCount be 0.
  9. Else if skipCount is not present, then
    1. Let actualSkipCount be len - actualStart.
  10. Else,
    1. Let sc be ? ToIntegerOrInfinity(skipCount).
    2. Let actualSkipCount be the result of clamping sc between 0 and len - actualStart.
  11. Let newLen be len + insertCount - actualSkipCount.
  12. If newLen > 253 - 1, throw a TypeError exception.
  13. Let A be ? ArrayCreate(newLen).
  14. Let i be 0.
  15. Let r be actualStart + actualSkipCount.
  16. Repeat, while i < actualStart,
    1. Let Pi be ! ToString(𝔽(i)).
    2. Let iValue be ? Get(O, Pi).
    3. Perform ! CreateDataPropertyOrThrow(A, Pi, iValue).
    4. Set i to i + 1.
  17. For each element E of items, do
    1. Let Pi be ! ToString(𝔽(i)).
    2. Perform ! CreateDataPropertyOrThrow(A, Pi, E).
    3. Set i to i + 1.
  18. Repeat, while i < newLen,
    1. Let Pi be ! ToString(𝔽(i)).
    2. Let from be ! ToString(𝔽(r)).
    3. Let fromValue be ? Get(O, from).
    4. Perform ! CreateDataPropertyOrThrow(A, Pi, fromValue).
    5. Set i to i + 1.
    6. Set r to r + 1.
  19. Return A.

23.1.3.36 Array.prototype.toString ( )

This method performs the following steps when called:

  1. Let array be ? ToObject(this value).
  2. Let func be ? Get(array, "join").
  3. If IsCallable(func) is false, set func to the intrinsic function %Object.prototype.toString%.
  4. Return ? Call(func, array).
Note

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.37 Array.prototype.unshift ( ...items )

This method prepends the arguments to the start of the array, such that their order within the array is the same as the order in which they appear in the argument list.

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let argCount be the number of elements in items.
  4. If argCount > 0, then
    1. If len + argCount > 253 - 1, throw a TypeError exception.
    2. Let k be len.
    3. Repeat, while k > 0,
      1. Let from be ! ToString(𝔽(k - 1)).
      2. Let to be ! ToString(𝔽(k + argCount - 1)).
      3. Let fromPresent be ? HasProperty(O, from).
      4. If fromPresent is true, then
        1. Let fromValue be ? Get(O, from).
        2. Perform ? Set(O, to, fromValue, true).
      5. Else,
        1. Assert: fromPresent is false.
        2. Perform ? DeletePropertyOrThrow(O, to).
      6. Set k to k - 1.
    4. Let j be +0𝔽.
    5. For each element E of items, do
      1. Perform ? Set(O, ! ToString(j), E, true).
      2. Set j to j + 1𝔽.
  5. Perform ? Set(O, "length", 𝔽(len + argCount), true).
  6. Return 𝔽(len + argCount).

The "length" property of this method is 1𝔽.

Note

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.38 Array.prototype.values ( )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Return CreateArrayIterator(O, value).

23.1.3.39 Array.prototype.with ( index, value )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeIndex be ? ToIntegerOrInfinity(index).
  4. If relativeIndex ≥ 0, let actualIndex be relativeIndex.
  5. Else, let actualIndex be len + relativeIndex.
  6. If actualIndexlen or actualIndex < 0, throw a RangeError exception.
  7. Let A be ? ArrayCreate(len).
  8. Let k be 0.
  9. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. If k is actualIndex, let fromValue be value.
    3. Else, let fromValue be ? Get(O, Pk).
    4. Perform ! CreateDataPropertyOrThrow(A, Pk, fromValue).
    5. Set k to k + 1.
  10. Return A.

23.1.3.40 Array.prototype [ @@iterator ] ( )

The initial value of the @@iterator property is %Array.prototype.values%, defined in 23.1.3.38.

23.1.3.41 Array.prototype [ @@unscopables ]

The initial value of the @@unscopables data property is an object created by the following steps:

  1. Let unscopableList be OrdinaryObjectCreate(null).
  2. Perform ! CreateDataPropertyOrThrow(unscopableList, "at", true).
  3. Perform ! CreateDataPropertyOrThrow(unscopableList, "copyWithin", true).
  4. Perform ! CreateDataPropertyOrThrow(unscopableList, "entries", true).
  5. Perform ! CreateDataPropertyOrThrow(unscopableList, "fill", true).
  6. Perform ! CreateDataPropertyOrThrow(unscopableList, "find", true).
  7. Perform ! CreateDataPropertyOrThrow(unscopableList, "findIndex", true).
  8. Perform ! CreateDataPropertyOrThrow(unscopableList, "findLast", true).
  9. Perform ! CreateDataPropertyOrThrow(unscopableList, "findLastIndex", true).
  10. Perform ! CreateDataPropertyOrThrow(unscopableList, "flat", true).
  11. Perform ! CreateDataPropertyOrThrow(unscopableList, "flatMap", true).
  12. Perform ! CreateDataPropertyOrThrow(unscopableList, "includes", true).
  13. Perform ! CreateDataPropertyOrThrow(unscopableList, "keys", true).
  14. Perform ! CreateDataPropertyOrThrow(unscopableList, "toReversed", true).
  15. Perform ! CreateDataPropertyOrThrow(unscopableList, "toSorted", true).
  16. Perform ! CreateDataPropertyOrThrow(unscopableList, "toSpliced", true).
  17. Perform ! CreateDataPropertyOrThrow(unscopableList, "values", true).
  18. Return unscopableList.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Note

The own property names of this object are property names that were not included as standard properties of Array.prototype prior to the ECMAScript 2015 specification. These names are ignored for with statement binding purposes in order to preserve the behaviour of existing code that might use one of these names as a binding in an outer scope that is shadowed by a with statement whose binding object is an Array.

The reason that "with" is not included in the unscopableList is because it is already a reserved word.

23.1.4 Properties of Array Instances

Array instances are Array exotic objects and have the internal methods specified for such objects. Array instances inherit properties from the Array prototype object.

Array instances have a "length" property, and a set of enumerable properties with array index names.

23.1.4.1 length

The "length" property of an Array instance is a data property whose value is always numerically greater than the name of every configurable own property whose name is an array index.

The "length" property initially has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Reducing the value of the "length" property has the side-effect of deleting own array elements whose array index is between the old and new length values. However, non-configurable properties can not be deleted. Attempting to set the "length" property of an Array to a value that is numerically less than or equal to the largest numeric own property name of an existing non-configurable array-indexed property of the array will result in the length being set to a numeric value that is one greater than that non-configurable numeric own property name. See 10.4.2.1.

23.1.5 Array Iterator Objects

An Array Iterator is an object, that represents a specific iteration over some specific Array instance object. There is not a named constructor for Array Iterator objects. Instead, Array iterator objects are created by calling certain methods of Array instance objects.

23.1.5.1 CreateArrayIterator ( array, kind )

The abstract operation CreateArrayIterator takes arguments array (an Object) and kind (key+value, key, or value) and returns a Generator. It is used to create iterator objects for Array methods that return such iterators. It performs the following steps when called:

  1. Let closure be a new Abstract Closure with no parameters that captures kind and array and performs the following steps when called:
    1. Let index be 0.
    2. Repeat,
      1. If array has a [[TypedArrayName]] internal slot, then
        1. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(array, seq-cst).
        2. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
        3. Let len be TypedArrayLength(taRecord).
      2. Else,
        1. Let len be ? LengthOfArrayLike(array).
      3. If indexlen, return NormalCompletion(undefined).
      4. Let indexNumber be 𝔽(index).
      5. If kind is key, then
        1. Let result be indexNumber.
      6. Else,
        1. Let elementKey be ! ToString(indexNumber).
        2. Let elementValue be ? Get(array, elementKey).
        3. If kind is value, then
          1. Let result be elementValue.
        4. Else,
          1. Assert: kind is key+value.
          2. Let result be CreateArrayFromListindexNumber, elementValue »).
      7. Perform ? GeneratorYield(CreateIterResultObject(result, false)).
      8. Set index to index + 1.
  2. Return CreateIteratorFromClosure(closure, "%ArrayIteratorPrototype%", %ArrayIteratorPrototype%).

23.1.5.2 The %ArrayIteratorPrototype% Object

The %ArrayIteratorPrototype% object:

  • has properties that are inherited by all Array Iterator Objects.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %IteratorPrototype%.
  • has the following properties:

23.1.5.2.1 %ArrayIteratorPrototype%.next ( )

  1. Return ? GeneratorResume(this value, empty, "%ArrayIteratorPrototype%").

23.1.5.2.2 %ArrayIteratorPrototype% [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Array Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

23.2 TypedArray Objects

A TypedArray presents an array-like view of an underlying binary data buffer (25.1). A TypedArray element type is the underlying binary scalar data type that all elements of a TypedArray instance have. There is a distinct TypedArray constructor, listed in Table 71, for each of the supported element types. Each constructor in Table 71 has a corresponding distinct prototype object.

Table 71: The TypedArray Constructors
Constructor Name and Intrinsic Element Type Element Size Conversion Operation Description
Int8Array
%Int8Array%
int8 1 ToInt8 8-bit two's complement signed integer
Uint8Array
%Uint8Array%
uint8 1 ToUint8 8-bit unsigned integer
Uint8ClampedArray
%Uint8ClampedArray%
uint8clamped 1 ToUint8Clamp 8-bit unsigned integer (clamped conversion)
Int16Array
%Int16Array%
int16 2 ToInt16 16-bit two's complement signed integer
Uint16Array
%Uint16Array%
uint16 2 ToUint16 16-bit unsigned integer
Int32Array
%Int32Array%
int32 4 ToInt32 32-bit two's complement signed integer
Uint32Array
%Uint32Array%
uint32 4 ToUint32 32-bit unsigned integer
BigInt64Array
%BigInt64Array%
bigint64 8 ToBigInt64 64-bit two's complement signed integer
BigUint64Array
%BigUint64Array%
biguint64 8 ToBigUint64 64-bit unsigned integer
Float32Array
%Float32Array%
float32 4 32-bit IEEE floating point
Float64Array
%Float64Array%
float64 8 64-bit IEEE floating point

In the definitions below, references to TypedArray should be replaced with the appropriate constructor name from the above table.

23.2.1 The %TypedArray% Intrinsic Object

The %TypedArray% intrinsic object:

  • is a constructor function object that all of the TypedArray constructor objects inherit from.
  • along with its corresponding prototype object, provides common properties that are inherited by all TypedArray constructors and their instances.
  • does not have a global name or appear as a property of the global object.
  • acts as the abstract superclass of the various TypedArray constructors.
  • will throw an error when invoked, because it is an abstract class constructor. The TypedArray constructors do not perform a super call to it.

23.2.1.1 %TypedArray% ( )

This function performs the following steps when called:

  1. Throw a TypeError exception.

The "length" property of this function is +0𝔽.

23.2.2 Properties of the %TypedArray% Intrinsic Object

The %TypedArray% intrinsic object:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has a "name" property whose value is "TypedArray".
  • has the following properties:

23.2.2.1 %TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )

This method performs the following steps when called:

  1. Let C be the this value.
  2. If IsConstructor(C) is false, throw a TypeError exception.
  3. If mapfn is undefined, then
    1. Let mapping be false.
  4. Else,
    1. If IsCallable(mapfn) is false, throw a TypeError exception.
    2. Let mapping be true.
  5. Let usingIterator be ? GetMethod(source, @@iterator).
  6. If usingIterator is not undefined, then
    1. Let values be ? IteratorToList(? GetIteratorFromMethod(source, usingIterator)).
    2. Let len be the number of elements in values.
    3. Let targetObj be ? TypedArrayCreateFromConstructor(C, « 𝔽(len) »).
    4. Let k be 0.
    5. Repeat, while k < len,
      1. Let Pk be ! ToString(𝔽(k)).
      2. Let kValue be the first element of values.
      3. Remove the first element from values.
      4. If mapping is true, then
        1. Let mappedValue be ? Call(mapfn, thisArg, « kValue, 𝔽(k) »).
      5. Else,
        1. Let mappedValue be kValue.
      6. Perform ? Set(targetObj, Pk, mappedValue, true).
      7. Set k to k + 1.
    6. Assert: values is now an empty List.
    7. Return targetObj.
  7. NOTE: source is not an Iterable so assume it is already an array-like object.
  8. Let arrayLike be ! ToObject(source).
  9. Let len be ? LengthOfArrayLike(arrayLike).
  10. Let targetObj be ? TypedArrayCreateFromConstructor(C, « 𝔽(len) »).
  11. Let k be 0.
  12. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ? Get(arrayLike, Pk).
    3. If mapping is true, then
      1. Let mappedValue be ? Call(mapfn, thisArg, « kValue, 𝔽(k) »).
    4. Else,
      1. Let mappedValue be kValue.
    5. Perform ? Set(targetObj, Pk, mappedValue, true).
    6. Set k to k + 1.
  13. Return targetObj.

23.2.2.2 %TypedArray%.of ( ...items )

This method performs the following steps when called:

  1. Let len be the number of elements in items.
  2. Let C be the this value.
  3. If IsConstructor(C) is false, throw a TypeError exception.
  4. Let newObj be ? TypedArrayCreateFromConstructor(C, « 𝔽(len) »).
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let kValue be items[k].
    2. Let Pk be ! ToString(𝔽(k)).
    3. Perform ? Set(newObj, Pk, kValue, true).
    4. Set k to k + 1.
  7. Return newObj.

23.2.2.3 %TypedArray%.prototype

The initial value of %TypedArray%.prototype is the %TypedArray% prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.2.2.4 get %TypedArray% [ @@species ]

%TypedArray%[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

%TypedArray.prototype% methods normally use their this value's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.

23.2.3 Properties of the %TypedArray% Prototype Object

The %TypedArray% prototype object:

  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is %TypedArray.prototype%.
  • is an ordinary object.
  • does not have a [[ViewedArrayBuffer]] or any other of the internal slots that are specific to TypedArray instance objects.

23.2.3.1 %TypedArray%.prototype.at ( index )

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let relativeIndex be ? ToIntegerOrInfinity(index).
  5. If relativeIndex ≥ 0, then
    1. Let k be relativeIndex.
  6. Else,
    1. Let k be len + relativeIndex.
  7. If k < 0 or klen, return undefined.
  8. Return ! Get(O, ! ToString(𝔽(k))).

23.2.3.2 get %TypedArray%.prototype.buffer

%TypedArray%.prototype.buffer is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let buffer be O.[[ViewedArrayBuffer]].
  5. Return buffer.

23.2.3.3 get %TypedArray%.prototype.byteLength

%TypedArray%.prototype.byteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  5. Let size be TypedArrayByteLength(taRecord).
  6. Return 𝔽(size).

23.2.3.4 get %TypedArray%.prototype.byteOffset

%TypedArray%.prototype.byteOffset is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  5. If IsTypedArrayOutOfBounds(taRecord) is true, return +0𝔽.
  6. Let offset be O.[[ByteOffset]].
  7. Return 𝔽(offset).

23.2.3.5 %TypedArray%.prototype.constructor

The initial value of %TypedArray%.prototype.constructor is %TypedArray%.

23.2.3.6 %TypedArray%.prototype.copyWithin ( target, start [ , end ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.copyWithin as defined in 23.1.3.4.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let relativeTarget be ? ToIntegerOrInfinity(target).
  5. If relativeTarget = -∞, let targetIndex be 0.
  6. Else if relativeTarget < 0, let targetIndex be max(len + relativeTarget, 0).
  7. Else, let targetIndex be min(relativeTarget, len).
  8. Let relativeStart be ? ToIntegerOrInfinity(start).
  9. If relativeStart = -∞, let startIndex be 0.
  10. Else if relativeStart < 0, let startIndex be max(len + relativeStart, 0).
  11. Else, let startIndex be min(relativeStart, len).
  12. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  13. If relativeEnd = -∞, let endIndex be 0.
  14. Else if relativeEnd < 0, let endIndex be max(len + relativeEnd, 0).
  15. Else, let endIndex be min(relativeEnd, len).
  16. Let count be min(endIndex - startIndex, len - targetIndex).
  17. If count > 0, then
    1. NOTE: The copying must be performed in a manner that preserves the bit-level encoding of the source data.
    2. Let buffer be O.[[ViewedArrayBuffer]].
    3. Set taRecord to MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
    4. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
    5. Set len to TypedArrayLength(taRecord).
    6. Let elementSize be TypedArrayElementSize(O).
    7. Let byteOffset be O.[[ByteOffset]].
    8. Let bufferByteLimit be (len × elementSize) + byteOffset.
    9. Let toByteIndex be (targetIndex × elementSize) + byteOffset.
    10. Let fromByteIndex be (startIndex × elementSize) + byteOffset.
    11. Let countBytes be count × elementSize.
    12. If fromByteIndex < toByteIndex and toByteIndex < fromByteIndex + countBytes, then
      1. Let direction be -1.
      2. Set fromByteIndex to fromByteIndex + countBytes - 1.
      3. Set toByteIndex to toByteIndex + countBytes - 1.
    13. Else,
      1. Let direction be 1.
    14. Repeat, while countBytes > 0,
      1. If fromByteIndex < bufferByteLimit and toByteIndex < bufferByteLimit, then
        1. Let value be GetValueFromBuffer(buffer, fromByteIndex, uint8, true, unordered).
        2. Perform SetValueInBuffer(buffer, toByteIndex, uint8, value, true, unordered).
        3. Set fromByteIndex to fromByteIndex + direction.
        4. Set toByteIndex to toByteIndex + direction.
        5. Set countBytes to countBytes - 1.
      2. Else,
        1. Set countBytes to 0.
  18. Return O.

23.2.3.7 %TypedArray%.prototype.entries ( )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O, seq-cst).
  3. Return CreateArrayIterator(O, key+value).

23.2.3.8 %TypedArray%.prototype.every ( callbackfn [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.every as defined in 23.1.3.6.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Let testResult be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
    4. If testResult is false, return false.
    5. Set k to k + 1.
  7. Return true.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.9 %TypedArray%.prototype.fill ( value [ , start [ , end ] ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.fill as defined in 23.1.3.7.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If O.[[ContentType]] is bigint, set value to ? ToBigInt(value).
  5. Otherwise, set value to ? ToNumber(value).
  6. Let relativeStart be ? ToIntegerOrInfinity(start).
  7. If relativeStart = -∞, let startIndex be 0.
  8. Else if relativeStart < 0, let startIndex be max(len + relativeStart, 0).
  9. Else, let startIndex be min(relativeStart, len).
  10. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  11. If relativeEnd = -∞, let endIndex be 0.
  12. Else if relativeEnd < 0, let endIndex be max(len + relativeEnd, 0).
  13. Else, let endIndex be min(relativeEnd, len).
  14. Set taRecord to MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  15. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
  16. Set len to TypedArrayLength(taRecord).
  17. Set endIndex to min(endIndex, len).
  18. Let k be startIndex.
  19. Repeat, while k < endIndex,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Perform ! Set(O, Pk, value, true).
    3. Set k to k + 1.
  20. Return O.

23.2.3.10 %TypedArray%.prototype.filter ( callbackfn [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.filter as defined in 23.1.3.8.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. Let kept be a new empty List.
  6. Let captured be 0.
  7. Let k be 0.
  8. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Let selected be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
    4. If selected is true, then
      1. Append kValue to kept.
      2. Set captured to captured + 1.
    5. Set k to k + 1.
  9. Let A be ? TypedArraySpeciesCreate(O, « 𝔽(captured) »).
  10. Let n be 0.
  11. For each element e of kept, do
    1. Perform ! Set(A, ! ToString(𝔽(n)), e, true).
    2. Set n to n + 1.
  12. Return A.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.11 %TypedArray%.prototype.find ( predicate [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.find as defined in 23.1.3.9.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let findRec be ? FindViaPredicate(O, len, ascending, predicate, thisArg).
  5. Return findRec.[[Value]].

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.12 %TypedArray%.prototype.findIndex ( predicate [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.findIndex as defined in 23.1.3.10.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let findRec be ? FindViaPredicate(O, len, ascending, predicate, thisArg).
  5. Return findRec.[[Index]].

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.13 %TypedArray%.prototype.findLast ( predicate [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.findLast as defined in 23.1.3.11.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let findRec be ? FindViaPredicate(O, len, descending, predicate, thisArg).
  5. Return findRec.[[Value]].

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.14 %TypedArray%.prototype.findLastIndex ( predicate [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.findLastIndex as defined in 23.1.3.12.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let findRec be ? FindViaPredicate(O, len, descending, predicate, thisArg).
  5. Return findRec.[[Index]].

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.15 %TypedArray%.prototype.forEach ( callbackfn [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.forEach as defined in 23.1.3.15.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Perform ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
    4. Set k to k + 1.
  7. Return undefined.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.16 %TypedArray%.prototype.includes ( searchElement [ , fromIndex ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.includes as defined in 23.1.3.16.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If len = 0, return false.
  5. Let n be ? ToIntegerOrInfinity(fromIndex).
  6. Assert: If fromIndex is undefined, then n is 0.
  7. If n = +∞, return false.
  8. Else if n = -∞, set n to 0.
  9. If n ≥ 0, then
    1. Let k be n.
  10. Else,
    1. Let k be len + n.
    2. If k < 0, set k to 0.
  11. Repeat, while k < len,
    1. Let elementK be ! Get(O, ! ToString(𝔽(k))).
    2. If SameValueZero(searchElement, elementK) is true, return true.
    3. Set k to k + 1.
  12. Return false.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.17 %TypedArray%.prototype.indexOf ( searchElement [ , fromIndex ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.indexOf as defined in 23.1.3.17.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If len = 0, return -1𝔽.
  5. Let n be ? ToIntegerOrInfinity(fromIndex).
  6. Assert: If fromIndex is undefined, then n is 0.
  7. If n = +∞, return -1𝔽.
  8. Else if n = -∞, set n to 0.
  9. If n ≥ 0, then
    1. Let k be n.
  10. Else,
    1. Let k be len + n.
    2. If k < 0, set k to 0.
  11. Repeat, while k < len,
    1. Let kPresent be ! HasProperty(O, ! ToString(𝔽(k))).
    2. If kPresent is true, then
      1. Let elementK be ! Get(O, ! ToString(𝔽(k))).
      2. If IsStrictlyEqual(searchElement, elementK) is true, return 𝔽(k).
    3. Set k to k + 1.
  12. Return -1𝔽.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.18 %TypedArray%.prototype.join ( separator )

The interpretation and use of the arguments of this method are the same as for Array.prototype.join as defined in 23.1.3.18.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If separator is undefined, let sep be ",".
  5. Else, let sep be ? ToString(separator).
  6. Let R be the empty String.
  7. Let k be 0.
  8. Repeat, while k < len,
    1. If k > 0, set R to the string-concatenation of R and sep.
    2. Let element be ! Get(O, ! ToString(𝔽(k))).
    3. If element is undefined, let next be the empty String; otherwise, let next be ! ToString(element).
    4. Set R to the string-concatenation of R and next.
    5. Set k to k + 1.
  9. Return R.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.19 %TypedArray%.prototype.keys ( )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O, seq-cst).
  3. Return CreateArrayIterator(O, key).

23.2.3.20 %TypedArray%.prototype.lastIndexOf ( searchElement [ , fromIndex ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.lastIndexOf as defined in 23.1.3.20.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If len = 0, return -1𝔽.
  5. If fromIndex is present, let n be ? ToIntegerOrInfinity(fromIndex); else let n be len - 1.
  6. If n = -∞, return -1𝔽.
  7. If n ≥ 0, then
    1. Let k be min(n, len - 1).
  8. Else,
    1. Let k be len + n.
  9. Repeat, while k ≥ 0,
    1. Let kPresent be ! HasProperty(O, ! ToString(𝔽(k))).
    2. If kPresent is true, then
      1. Let elementK be ! Get(O, ! ToString(𝔽(k))).
      2. If IsStrictlyEqual(searchElement, elementK) is true, return 𝔽(k).
    3. Set k to k - 1.
  10. Return -1𝔽.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.21 get %TypedArray%.prototype.length

%TypedArray%.prototype.length is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  3. Assert: O has [[ViewedArrayBuffer]] and [[ArrayLength]] internal slots.
  4. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  5. If IsTypedArrayOutOfBounds(taRecord) is true, return +0𝔽.
  6. Let length be TypedArrayLength(taRecord).
  7. Return 𝔽(length).

This function is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.22 %TypedArray%.prototype.map ( callbackfn [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.map as defined in 23.1.3.21.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. Let A be ? TypedArraySpeciesCreate(O, « 𝔽(len) »).
  6. Let k be 0.
  7. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Let mappedValue be ? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »).
    4. Perform ? Set(A, Pk, mappedValue, true).
    5. Set k to k + 1.
  8. Return A.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.23 %TypedArray%.prototype.reduce ( callbackfn [ , initialValue ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.reduce as defined in 23.1.3.24.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. If len = 0 and initialValue is not present, throw a TypeError exception.
  6. Let k be 0.
  7. Let accumulator be undefined.
  8. If initialValue is present, then
    1. Set accumulator to initialValue.
  9. Else,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Set accumulator to ! Get(O, Pk).
    3. Set k to k + 1.
  10. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »).
    4. Set k to k + 1.
  11. Return accumulator.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.24 %TypedArray%.prototype.reduceRight ( callbackfn [ , initialValue ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.reduceRight as defined in 23.1.3.25.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. If len = 0 and initialValue is not present, throw a TypeError exception.
  6. Let k be len - 1.
  7. Let accumulator be undefined.
  8. If initialValue is present, then
    1. Set accumulator to initialValue.
  9. Else,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Set accumulator to ! Get(O, Pk).
    3. Set k to k - 1.
  10. Repeat, while k ≥ 0,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Set accumulator to ? Call(callbackfn, undefined, « accumulator, kValue, 𝔽(k), O »).
    4. Set k to k - 1.
  11. Return accumulator.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.25 %TypedArray%.prototype.reverse ( )

The interpretation and use of the arguments of this method are the same as for Array.prototype.reverse as defined in 23.1.3.26.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let middle be floor(len / 2).
  5. Let lower be 0.
  6. Repeat, while lowermiddle,
    1. Let upper be len - lower - 1.
    2. Let upperP be ! ToString(𝔽(upper)).
    3. Let lowerP be ! ToString(𝔽(lower)).
    4. Let lowerValue be ! Get(O, lowerP).
    5. Let upperValue be ! Get(O, upperP).
    6. Perform ! Set(O, lowerP, upperValue, true).
    7. Perform ! Set(O, upperP, lowerValue, true).
    8. Set lower to lower + 1.
  7. Return O.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.26 %TypedArray%.prototype.set ( source [ , offset ] )

This method sets multiple values in this TypedArray, reading the values from source. The details differ based upon the type of source. The optional offset value indicates the first element index in this TypedArray where values are written. If omitted, it is assumed to be 0.

It performs the following steps when called:

  1. Let target be the this value.
  2. Perform ? RequireInternalSlot(target, [[TypedArrayName]]).
  3. Assert: target has a [[ViewedArrayBuffer]] internal slot.
  4. Let targetOffset be ? ToIntegerOrInfinity(offset).
  5. If targetOffset < 0, throw a RangeError exception.
  6. If source is an Object that has a [[TypedArrayName]] internal slot, then
    1. Perform ? SetTypedArrayFromTypedArray(target, targetOffset, source).
  7. Else,
    1. Perform ? SetTypedArrayFromArrayLike(target, targetOffset, source).
  8. Return undefined.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.26.1 SetTypedArrayFromTypedArray ( target, targetOffset, source )

The abstract operation SetTypedArrayFromTypedArray takes arguments target (a TypedArray), targetOffset (a non-negative integer or +∞), and source (a TypedArray) and returns either a normal completion containing unused or a throw completion. It sets multiple values in target, starting at index targetOffset, reading the values from source. It performs the following steps when called:

  1. Let targetBuffer be target.[[ViewedArrayBuffer]].
  2. Let targetRecord be MakeTypedArrayWithBufferWitnessRecord(target, seq-cst).
  3. If IsTypedArrayOutOfBounds(targetRecord) is true, throw a TypeError exception.
  4. Let targetLength be TypedArrayLength(targetRecord).
  5. Let srcBuffer be source.[[ViewedArrayBuffer]].
  6. Let srcRecord be MakeTypedArrayWithBufferWitnessRecord(source, seq-cst).
  7. If IsTypedArrayOutOfBounds(srcRecord) is true, throw a TypeError exception.
  8. Let srcLength be TypedArrayLength(srcRecord).
  9. Let targetType be TypedArrayElementType(target).
  10. Let targetElementSize be TypedArrayElementSize(target).
  11. Let targetByteOffset be target.[[ByteOffset]].
  12. Let srcType be TypedArrayElementType(source).
  13. Let srcElementSize be TypedArrayElementSize(source).
  14. Let srcByteOffset be source.[[ByteOffset]].
  15. If targetOffset = +∞, throw a RangeError exception.
  16. If srcLength + targetOffset > targetLength, throw a RangeError exception.
  17. If target.[[ContentType]] is not source.[[ContentType]], throw a TypeError exception.
  18. If IsSharedArrayBuffer(srcBuffer) is true, IsSharedArrayBuffer(targetBuffer) is true, and srcBuffer.[[ArrayBufferData]] is targetBuffer.[[ArrayBufferData]], let sameSharedArrayBuffer be true; otherwise, let sameSharedArrayBuffer be false.
  19. If SameValue(srcBuffer, targetBuffer) is true or sameSharedArrayBuffer is true, then
    1. Let srcByteLength be TypedArrayByteLength(srcRecord).
    2. Set srcBuffer to ? CloneArrayBuffer(srcBuffer, srcByteOffset, srcByteLength).
    3. Let srcByteIndex be 0.
  20. Else,
    1. Let srcByteIndex be srcByteOffset.
  21. Let targetByteIndex be (targetOffset × targetElementSize) + targetByteOffset.
  22. Let limit be targetByteIndex + (targetElementSize × srcLength).
  23. If srcType is targetType, then
    1. NOTE: The transfer must be performed in a manner that preserves the bit-level encoding of the source data.
    2. Repeat, while targetByteIndex < limit,
      1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, uint8, true, unordered).
      2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, uint8, value, true, unordered).
      3. Set srcByteIndex to srcByteIndex + 1.
      4. Set targetByteIndex to targetByteIndex + 1.
  24. Else,
    1. Repeat, while targetByteIndex < limit,
      1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, srcType, true, unordered).
      2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, targetType, value, true, unordered).
      3. Set srcByteIndex to srcByteIndex + srcElementSize.
      4. Set targetByteIndex to targetByteIndex + targetElementSize.
  25. Return unused.

23.2.3.26.2 SetTypedArrayFromArrayLike ( target, targetOffset, source )

The abstract operation SetTypedArrayFromArrayLike takes arguments target (a TypedArray), targetOffset (a non-negative integer or +∞), and source (an ECMAScript language value, but not a TypedArray) and returns either a normal completion containing unused or a throw completion. It sets multiple values in target, starting at index targetOffset, reading the values from source. It performs the following steps when called:

  1. Let targetRecord be MakeTypedArrayWithBufferWitnessRecord(target, seq-cst).
  2. If IsTypedArrayOutOfBounds(targetRecord) is true, throw a TypeError exception.
  3. Let targetLength be TypedArrayLength(targetRecord).
  4. Let src be ? ToObject(source).
  5. Let srcLength be ? LengthOfArrayLike(src).
  6. If targetOffset = +∞, throw a RangeError exception.
  7. If srcLength + targetOffset > targetLength, throw a RangeError exception.
  8. Let k be 0.
  9. Repeat, while k < srcLength,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let value be ? Get(src, Pk).
    3. Let targetIndex be 𝔽(targetOffset + k).
    4. Perform ? TypedArraySetElement(target, targetIndex, value).
    5. Set k to k + 1.
  10. Return unused.

23.2.3.27 %TypedArray%.prototype.slice ( start, end )

The interpretation and use of the arguments of this method are the same as for Array.prototype.slice as defined in 23.1.3.28.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let srcArrayLength be TypedArrayLength(taRecord).
  4. Let relativeStart be ? ToIntegerOrInfinity(start).
  5. If relativeStart = -∞, let startIndex be 0.
  6. Else if relativeStart < 0, let startIndex be max(srcArrayLength + relativeStart, 0).
  7. Else, let startIndex be min(relativeStart, srcArrayLength).
  8. If end is undefined, let relativeEnd be srcArrayLength; else let relativeEnd be ? ToIntegerOrInfinity(end).
  9. If relativeEnd = -∞, let endIndex be 0.
  10. Else if relativeEnd < 0, let endIndex be max(srcArrayLength + relativeEnd, 0).
  11. Else, let endIndex be min(relativeEnd, srcArrayLength).
  12. Let countBytes be max(endIndex - startIndex, 0).
  13. Let A be ? TypedArraySpeciesCreate(O, « 𝔽(countBytes) »).
  14. If countBytes > 0, then
    1. Set taRecord to MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
    2. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
    3. Set endIndex to min(endIndex, TypedArrayLength(taRecord)).
    4. Set countBytes to max(endIndex - startIndex, 0).
    5. Let srcType be TypedArrayElementType(O).
    6. Let targetType be TypedArrayElementType(A).
    7. If srcType is targetType, then
      1. NOTE: The transfer must be performed in a manner that preserves the bit-level encoding of the source data.
      2. Let srcBuffer be O.[[ViewedArrayBuffer]].
      3. Let targetBuffer be A.[[ViewedArrayBuffer]].
      4. Let elementSize be TypedArrayElementSize(O).
      5. Let srcByteOffset be O.[[ByteOffset]].
      6. Let srcByteIndex be (startIndex × elementSize) + srcByteOffset.
      7. Let targetByteIndex be A.[[ByteOffset]].
      8. Let endByteIndex be targetByteIndex + (countBytes × elementSize).
      9. Repeat, while targetByteIndex < endByteIndex,
        1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, uint8, true, unordered).
        2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, uint8, value, true, unordered).
        3. Set srcByteIndex to srcByteIndex + 1.
        4. Set targetByteIndex to targetByteIndex + 1.
    8. Else,
      1. Let n be 0.
      2. Let k be startIndex.
      3. Repeat, while k < endIndex,
        1. Let Pk be ! ToString(𝔽(k)).
        2. Let kValue be ! Get(O, Pk).
        3. Perform ! Set(A, ! ToString(𝔽(n)), kValue, true).
        4. Set k to k + 1.
        5. Set n to n + 1.
  15. Return A.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.28 %TypedArray%.prototype.some ( callbackfn [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.some as defined in 23.1.3.29.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callbackfn) is false, throw a TypeError exception.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Let testResult be ToBoolean(? Call(callbackfn, thisArg, « kValue, 𝔽(k), O »)).
    4. If testResult is true, return true.
    5. Set k to k + 1.
  7. Return false.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.29 %TypedArray%.prototype.sort ( comparefn )

This is a distinct method that, except as described below, implements the same requirements as those of Array.prototype.sort as defined in 23.1.3.30. The implementation of this method may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

It performs the following steps when called:

  1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
  2. Let obj be the this value.
  3. Let taRecord be ? ValidateTypedArray(obj, seq-cst).
  4. Let len be TypedArrayLength(taRecord).
  5. NOTE: The following closure performs a numeric comparison rather than the string comparison used in 23.1.3.30.
  6. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparefn and performs the following steps when called:
    1. Return ? CompareTypedArrayElements(x, y, comparefn).
  7. Let sortedList be ? SortIndexedProperties(obj, len, SortCompare, read-through-holes).
  8. Let j be 0.
  9. Repeat, while j < len,
    1. Perform ! Set(obj, ! ToString(𝔽(j)), sortedList[j], true).
    2. Set j to j + 1.
  10. Return obj.
Note

Because NaN always compares greater than any other value (see CompareTypedArrayElements), NaN property values always sort to the end of the result when comparefn is not provided.

23.2.3.30 %TypedArray%.prototype.subarray ( start, end )

This method returns a new TypedArray whose element type is the element type of this TypedArray and whose ArrayBuffer is the ArrayBuffer of this TypedArray, referencing the elements in the interval from start (inclusive) to end (exclusive). If either start or end is negative, it refers to an index from the end of the array, as opposed to from the beginning.

It performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let buffer be O.[[ViewedArrayBuffer]].
  5. Let srcRecord be MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  6. If IsTypedArrayOutOfBounds(srcRecord) is true, then
    1. Let srcLength be 0.
  7. Else,
    1. Let srcLength be TypedArrayLength(srcRecord).
  8. Let relativeStart be ? ToIntegerOrInfinity(start).
  9. If relativeStart = -∞, let startIndex be 0.
  10. Else if relativeStart < 0, let startIndex be max(srcLength + relativeStart, 0).
  11. Else, let startIndex be min(relativeStart, srcLength).
  12. Let elementSize be TypedArrayElementSize(O).
  13. Let srcByteOffset be O.[[ByteOffset]].
  14. Let beginByteOffset be srcByteOffset + (startIndex × elementSize).
  15. If O.[[ArrayLength]] is auto and end is undefined, then
    1. Let argumentsList be « buffer, 𝔽(beginByteOffset) ».
  16. Else,
    1. If end is undefined, let relativeEnd be srcLength; else let relativeEnd be ? ToIntegerOrInfinity(end).
    2. If relativeEnd = -∞, let endIndex be 0.
    3. Else if relativeEnd < 0, let endIndex be max(srcLength + relativeEnd, 0).
    4. Else, let endIndex be min(relativeEnd, srcLength).
    5. Let newLength be max(endIndex - startIndex, 0).
    6. Let argumentsList be « buffer, 𝔽(beginByteOffset), 𝔽(newLength) ».
  17. Return ? TypedArraySpeciesCreate(O, argumentsList).

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.31 %TypedArray%.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

This is a distinct method that implements the same algorithm as Array.prototype.toLocaleString as defined in 23.1.3.32 except that TypedArrayLength is called in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value has a fixed length when the underlying buffer is not resizable and whose integer-indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This method is not generic. ValidateTypedArray is called with the this value and seq-cst as arguments prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

Note

If the ECMAScript implementation includes the ECMA-402 Internationalization API this method is based upon the algorithm for Array.prototype.toLocaleString that is in the ECMA-402 specification.

23.2.3.32 %TypedArray%.prototype.toReversed ( )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let length be TypedArrayLength(taRecord).
  4. Let A be ? TypedArrayCreateSameType(O, « 𝔽(length) »).
  5. Let k be 0.
  6. Repeat, while k < length,
    1. Let from be ! ToString(𝔽(length - k - 1)).
    2. Let Pk be ! ToString(𝔽(k)).
    3. Let fromValue be ! Get(O, from).
    4. Perform ! Set(A, Pk, fromValue, true).
    5. Set k to k + 1.
  7. Return A.

23.2.3.33 %TypedArray%.prototype.toSorted ( comparefn )

This method performs the following steps when called:

  1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
  2. Let O be the this value.
  3. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  4. Let len be TypedArrayLength(taRecord).
  5. Let A be ? TypedArrayCreateSameType(O, « 𝔽(len) »).
  6. NOTE: The following closure performs a numeric comparison rather than the string comparison used in 23.1.3.34.
  7. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparefn and performs the following steps when called:
    1. Return ? CompareTypedArrayElements(x, y, comparefn).
  8. Let sortedList be ? SortIndexedProperties(O, len, SortCompare, read-through-holes).
  9. Let j be 0.
  10. Repeat, while j < len,
    1. Perform ! Set(A, ! ToString(𝔽(j)), sortedList[j], true).
    2. Set j to j + 1.
  11. Return A.

23.2.3.34 %TypedArray%.prototype.toString ( )

The initial value of the "toString" property is %Array.prototype.toString%, defined in 23.1.3.36.

23.2.3.35 %TypedArray%.prototype.values ( )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O, seq-cst).
  3. Return CreateArrayIterator(O, value).

23.2.3.36 %TypedArray%.prototype.with ( index, value )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let relativeIndex be ? ToIntegerOrInfinity(index).
  5. If relativeIndex ≥ 0, let actualIndex be relativeIndex.
  6. Else, let actualIndex be len + relativeIndex.
  7. If O.[[ContentType]] is bigint, let numericValue be ? ToBigInt(value).
  8. Else, let numericValue be ? ToNumber(value).
  9. If IsValidIntegerIndex(O, 𝔽(actualIndex)) is false, throw a RangeError exception.
  10. Let A be ? TypedArrayCreateSameType(O, « 𝔽(len) »).
  11. Let k be 0.
  12. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. If k is actualIndex, let fromValue be numericValue.
    3. Else, let fromValue be ! Get(O, Pk).
    4. Perform ! Set(A, Pk, fromValue, true).
    5. Set k to k + 1.
  13. Return A.

23.2.3.37 %TypedArray%.prototype [ @@iterator ] ( )

The initial value of the @@iterator property is %TypedArray.prototype.values%, defined in 23.2.3.35.

23.2.3.38 get %TypedArray%.prototype [ @@toStringTag ]

%TypedArray%.prototype[@@toStringTag] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, return undefined.
  3. If O does not have a [[TypedArrayName]] internal slot, return undefined.
  4. Let name be O.[[TypedArrayName]].
  5. Assert: name is a String.
  6. Return name.

This property has the attributes { [[Enumerable]]: false, [[Configurable]]: true }.

The initial value of the "name" property of this function is "get [Symbol.toStringTag]".

23.2.4 Abstract Operations for TypedArray Objects

23.2.4.1 TypedArraySpeciesCreate ( exemplar, argumentList )

The abstract operation TypedArraySpeciesCreate takes arguments exemplar (a TypedArray) and argumentList (a List of ECMAScript language values) and returns either a normal completion containing a TypedArray or a throw completion. It is used to specify the creation of a new TypedArray using a constructor function that is derived from exemplar. Unlike ArraySpeciesCreate, which can create non-Array objects through the use of @@species, this operation enforces that the constructor function creates an actual TypedArray. It performs the following steps when called:

  1. Let defaultConstructor be the intrinsic object associated with the constructor name exemplar.[[TypedArrayName]] in Table 71.
  2. Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
  3. Let result be ? TypedArrayCreateFromConstructor(constructor, argumentList).
  4. Assert: result has [[TypedArrayName]] and [[ContentType]] internal slots.
  5. If result.[[ContentType]] is not exemplar.[[ContentType]], throw a TypeError exception.
  6. Return result.

23.2.4.2 TypedArrayCreateFromConstructor ( constructor, argumentList )

The abstract operation TypedArrayCreateFromConstructor takes arguments constructor (a constructor) and argumentList (a List of ECMAScript language values) and returns either a normal completion containing a TypedArray or a throw completion. It is used to specify the creation of a new TypedArray using a constructor function. It performs the following steps when called:

  1. Let newTypedArray be ? Construct(constructor, argumentList).
  2. Let taRecord be ? ValidateTypedArray(newTypedArray, seq-cst).
  3. If the number of elements in argumentList is 1 and argumentList[0] is a Number, then
    1. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
    2. Let length be TypedArrayLength(taRecord).
    3. If length < (argumentList[0]), throw a TypeError exception.
  4. Return newTypedArray.

23.2.4.3 TypedArrayCreateSameType ( exemplar, argumentList )

The abstract operation TypedArrayCreateSameType takes arguments exemplar (a TypedArray) and argumentList (a List of ECMAScript language values) and returns either a normal completion containing a TypedArray or a throw completion. It is used to specify the creation of a new TypedArray using a constructor function that is derived from exemplar. Unlike TypedArraySpeciesCreate, which can construct custom TypedArray subclasses through the use of @@species, this operation always uses one of the built-in TypedArray constructors. It performs the following steps when called:

  1. Let constructor be the intrinsic object associated with the constructor name exemplar.[[TypedArrayName]] in Table 71.
  2. Let result be ? TypedArrayCreateFromConstructor(constructor, argumentList).
  3. Assert: result has [[TypedArrayName]] and [[ContentType]] internal slots.
  4. Assert: result.[[ContentType]] is exemplar.[[ContentType]].
  5. Return result.

23.2.4.4 ValidateTypedArray ( O, order )

The abstract operation ValidateTypedArray takes arguments O (an ECMAScript language value) and order (seq-cst or unordered) and returns either a normal completion containing a TypedArray With Buffer Witness Record or a throw completion. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  2. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  3. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, order).
  4. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
  5. Return taRecord.

23.2.4.5 TypedArrayElementSize ( O )

The abstract operation TypedArrayElementSize takes argument O (a TypedArray) and returns a non-negative integer. It performs the following steps when called:

  1. Return the Element Size value specified in Table 71 for O.[[TypedArrayName]].

23.2.4.6 TypedArrayElementType ( O )

The abstract operation TypedArrayElementType takes argument O (a TypedArray) and returns a TypedArray element type. It performs the following steps when called:

  1. Return the Element Type value specified in Table 71 for O.[[TypedArrayName]].

23.2.4.7 CompareTypedArrayElements ( x, y, comparefn )

The abstract operation CompareTypedArrayElements takes arguments x (a Number or a BigInt), y (a Number or a BigInt), and comparefn (a function object or undefined) and returns either a normal completion containing a Number or an abrupt completion. It performs the following steps when called:

  1. Assert: x is a Number and y is a Number, or x is a BigInt and y is a BigInt.
  2. If comparefn is not undefined, then
    1. Let v be ? ToNumber(? Call(comparefn, undefined, « x, y »)).
    2. If v is NaN, return +0𝔽.
    3. Return v.
  3. If x and y are both NaN, return +0𝔽.
  4. If x is NaN, return 1𝔽.
  5. If y is NaN, return -1𝔽.
  6. If x < y, return -1𝔽.
  7. If x > y, return 1𝔽.
  8. If x is -0𝔽 and y is +0𝔽, return -1𝔽.
  9. If x is +0𝔽 and y is -0𝔽, return 1𝔽.
  10. Return +0𝔽.
Note
This performs a numeric comparison rather than the string comparison used in 23.1.3.30.2.

23.2.5 The TypedArray Constructors

Each TypedArray constructor:

  • is an intrinsic object that has the structure described below, differing only in the name used as the constructor name instead of TypedArray, in Table 71.
  • is a function whose behaviour differs based upon the number and types of its arguments. The actual behaviour of a call of TypedArray depends upon the number and kind of arguments that are passed to it.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified TypedArray behaviour must include a super call to the TypedArray constructor to create and initialize the subclass instance with the internal state necessary to support the %TypedArray%.prototype built-in methods.

23.2.5.1 TypedArray ( ...args )

Each TypedArray constructor performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let constructorName be the String value of the Constructor Name value specified in Table 71 for this TypedArray constructor.
  3. Let proto be "%TypedArray.prototype%".
  4. Let numberOfArgs be the number of elements in args.
  5. If numberOfArgs = 0, then
    1. Return ? AllocateTypedArray(constructorName, NewTarget, proto, 0).
  6. Else,
    1. Let firstArgument be args[0].
    2. If firstArgument is an Object, then
      1. Let O be ? AllocateTypedArray(constructorName, NewTarget, proto).
      2. If firstArgument has a [[TypedArrayName]] internal slot, then
        1. Perform ? InitializeTypedArrayFromTypedArray(O, firstArgument).
      3. Else if firstArgument has an [[ArrayBufferData]] internal slot, then
        1. If numberOfArgs > 1, let byteOffset be args[1]; else let byteOffset be undefined.
        2. If numberOfArgs > 2, let length be args[2]; else let length be undefined.
        3. Perform ? InitializeTypedArrayFromArrayBuffer(O, firstArgument, byteOffset, length).
      4. Else,
        1. Assert: firstArgument is an Object and firstArgument does not have either a [[TypedArrayName]] or an [[ArrayBufferData]] internal slot.
        2. Let usingIterator be ? GetMethod(firstArgument, @@iterator).
        3. If usingIterator is not undefined, then
          1. Let values be ? IteratorToList(? GetIteratorFromMethod(firstArgument, usingIterator)).
          2. Perform ? InitializeTypedArrayFromList(O, values).
        4. Else,
          1. NOTE: firstArgument is not an Iterable so assume it is already an array-like object.
          2. Perform ? InitializeTypedArrayFromArrayLike(O, firstArgument).
      5. Return O.
    3. Else,
      1. Assert: firstArgument is not an Object.
      2. Let elementLength be ? ToIndex(firstArgument).
      3. Return ? AllocateTypedArray(constructorName, NewTarget, proto, elementLength).

23.2.5.1.1 AllocateTypedArray ( constructorName, newTarget, defaultProto [ , length ] )

The abstract operation AllocateTypedArray takes arguments constructorName (a String which is the name of a TypedArray constructor in Table 71), newTarget (a constructor), and defaultProto (a String) and optional argument length (a non-negative integer) and returns either a normal completion containing a TypedArray or a throw completion. It is used to validate and create an instance of a TypedArray constructor. If the length argument is passed, an ArrayBuffer of that length is also allocated and associated with the new TypedArray instance. AllocateTypedArray provides common semantics that is used by TypedArray. It performs the following steps when called:

  1. Let proto be ? GetPrototypeFromConstructor(newTarget, defaultProto).
  2. Let obj be TypedArrayCreate(proto).
  3. Assert: obj.[[ViewedArrayBuffer]] is undefined.
  4. Set obj.[[TypedArrayName]] to constructorName.
  5. If constructorName is either "BigInt64Array" or "BigUint64Array", set obj.[[ContentType]] to bigint.
  6. Otherwise, set obj.[[ContentType]] to number.
  7. If length is not present, then
    1. Set obj.[[ByteLength]] to 0.
    2. Set obj.[[ByteOffset]] to 0.
    3. Set obj.[[ArrayLength]] to 0.
  8. Else,
    1. Perform ? AllocateTypedArrayBuffer(obj, length).
  9. Return obj.

23.2.5.1.2 InitializeTypedArrayFromTypedArray ( O, srcArray )

The abstract operation InitializeTypedArrayFromTypedArray takes arguments O (a TypedArray) and srcArray (a TypedArray) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let srcData be srcArray.[[ViewedArrayBuffer]].
  2. Let elementType be TypedArrayElementType(O).
  3. Let elementSize be TypedArrayElementSize(O).
  4. Let srcType be TypedArrayElementType(srcArray).
  5. Let srcElementSize be TypedArrayElementSize(srcArray).
  6. Let srcByteOffset be srcArray.[[ByteOffset]].
  7. Let srcRecord be MakeTypedArrayWithBufferWitnessRecord(srcArray, seq-cst).
  8. If IsTypedArrayOutOfBounds(srcRecord) is true, throw a TypeError exception.
  9. Let elementLength be TypedArrayLength(srcRecord).
  10. Let byteLength be elementSize × elementLength.
  11. If elementType is srcType, then
    1. Let data be ? CloneArrayBuffer(srcData, srcByteOffset, byteLength).
  12. Else,
    1. Let data be ? AllocateArrayBuffer(%ArrayBuffer%, byteLength).
    2. If srcArray.[[ContentType]] is not O.[[ContentType]], throw a TypeError exception.
    3. Let srcByteIndex be srcByteOffset.
    4. Let targetByteIndex be 0.
    5. Let count be elementLength.
    6. Repeat, while count > 0,
      1. Let value be GetValueFromBuffer(srcData, srcByteIndex, srcType, true, unordered).
      2. Perform SetValueInBuffer(data, targetByteIndex, elementType, value, true, unordered).
      3. Set srcByteIndex to srcByteIndex + srcElementSize.
      4. Set targetByteIndex to targetByteIndex + elementSize.
      5. Set count to count - 1.
  13. Set O.[[ViewedArrayBuffer]] to data.
  14. Set O.[[ByteLength]] to byteLength.
  15. Set O.[[ByteOffset]] to 0.
  16. Set O.[[ArrayLength]] to elementLength.
  17. Return unused.

23.2.5.1.3 InitializeTypedArrayFromArrayBuffer ( O, buffer, byteOffset, length )

The abstract operation InitializeTypedArrayFromArrayBuffer takes arguments O (a TypedArray), buffer (an ArrayBuffer or a SharedArrayBuffer), byteOffset (an ECMAScript language value), and length (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let elementSize be TypedArrayElementSize(O).
  2. Let offset be ? ToIndex(byteOffset).
  3. If offset modulo elementSize ≠ 0, throw a RangeError exception.
  4. Let bufferIsFixedLength be IsFixedLengthArrayBuffer(buffer).
  5. If length is not undefined, then
    1. Let newLength be ? ToIndex(length).
  6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  7. Let bufferByteLength be ArrayBufferByteLength(buffer, seq-cst).
  8. If length is undefined and bufferIsFixedLength is false, then
    1. If offset > bufferByteLength, throw a RangeError exception.
    2. Set O.[[ByteLength]] to auto.
    3. Set O.[[ArrayLength]] to auto.
  9. Else,
    1. If length is undefined, then
      1. If bufferByteLength modulo elementSize ≠ 0, throw a RangeError exception.
      2. Let newByteLength be bufferByteLength - offset.
      3. If newByteLength < 0, throw a RangeError exception.
    2. Else,
      1. Let newByteLength be newLength × elementSize.
      2. If offset + newByteLength > bufferByteLength, throw a RangeError exception.
    3. Set O.[[ByteLength]] to newByteLength.
    4. Set O.[[ArrayLength]] to newByteLength / elementSize.
  10. Set O.[[ViewedArrayBuffer]] to buffer.
  11. Set O.[[ByteOffset]] to offset.
  12. Return unused.

23.2.5.1.4 InitializeTypedArrayFromList ( O, values )

The abstract operation InitializeTypedArrayFromList takes arguments O (a TypedArray) and values (a List of ECMAScript language values) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let len be the number of elements in values.
  2. Perform ? AllocateTypedArrayBuffer(O, len).
  3. Let k be 0.
  4. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be the first element of values.
    3. Remove the first element from values.
    4. Perform ? Set(O, Pk, kValue, true).
    5. Set k to k + 1.
  5. Assert: values is now an empty List.
  6. Return unused.

23.2.5.1.5 InitializeTypedArrayFromArrayLike ( O, arrayLike )

The abstract operation InitializeTypedArrayFromArrayLike takes arguments O (a TypedArray) and arrayLike (an Object, but not a TypedArray or an ArrayBuffer) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let len be ? LengthOfArrayLike(arrayLike).
  2. Perform ? AllocateTypedArrayBuffer(O, len).
  3. Let k be 0.
  4. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ? Get(arrayLike, Pk).
    3. Perform ? Set(O, Pk, kValue, true).
    4. Set k to k + 1.
  5. Return unused.

23.2.5.1.6 AllocateTypedArrayBuffer ( O, length )

The abstract operation AllocateTypedArrayBuffer takes arguments O (a TypedArray) and length (a non-negative integer) and returns either a normal completion containing unused or a throw completion. It allocates and associates an ArrayBuffer with O. It performs the following steps when called:

  1. Assert: O.[[ViewedArrayBuffer]] is undefined.
  2. Let elementSize be TypedArrayElementSize(O).
  3. Let byteLength be elementSize × length.
  4. Let data be ? AllocateArrayBuffer(%ArrayBuffer%, byteLength).
  5. Set O.[[ViewedArrayBuffer]] to data.
  6. Set O.[[ByteLength]] to byteLength.
  7. Set O.[[ByteOffset]] to 0.
  8. Set O.[[ArrayLength]] to length.
  9. Return unused.

23.2.6 Properties of the TypedArray Constructors

Each TypedArray constructor:

  • has a [[Prototype]] internal slot whose value is %TypedArray%.
  • has a "length" property whose value is 3𝔽.
  • has a "name" property whose value is the String value of the constructor name specified for it in Table 71.
  • has the following properties:

23.2.6.1 TypedArray.BYTES_PER_ELEMENT

The value of TypedArray.BYTES_PER_ELEMENT is the Element Size value specified in Table 71 for TypedArray.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.2.6.2 TypedArray.prototype

The initial value of TypedArray.prototype is the corresponding TypedArray prototype intrinsic object (23.2.7).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.2.7 Properties of the TypedArray Prototype Objects

Each TypedArray prototype object:

  • has a [[Prototype]] internal slot whose value is %TypedArray.prototype%.
  • is an ordinary object.
  • does not have a [[ViewedArrayBuffer]] or any other of the internal slots that are specific to TypedArray instance objects.

23.2.7.1 TypedArray.prototype.BYTES_PER_ELEMENT

The value of TypedArray.prototype.BYTES_PER_ELEMENT is the Element Size value specified in Table 71 for TypedArray.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.2.7.2 TypedArray.prototype.constructor

The initial value of the "constructor" property of the prototype for a given TypedArray constructor is the constructor itself.

23.2.8 Properties of TypedArray Instances

TypedArray instances are TypedArrays. Each TypedArray instance inherits properties from the corresponding TypedArray prototype object. Each TypedArray instance has the following internal slots: [[TypedArrayName]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]], and [[ArrayLength]].

24 Keyed Collections

24.1 Map Objects

Maps are collections of key/value pairs where both the keys and values may be arbitrary ECMAScript language values. A distinct key value may only occur in one key/value pair within the Map's collection. Distinct key values are discriminated using the SameValueZero comparison algorithm.

Maps must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structure used in this specification is only intended to describe the required observable semantics of Maps. It is not intended to be a viable implementation model.

24.1.1 The Map Constructor

The Map constructor:

  • is %Map%.
  • is the initial value of the "Map" property of the global object.
  • creates and initializes a new Map when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Map behaviour must include a super call to the Map constructor to create and initialize the subclass instance with the internal state necessary to support the Map.prototype built-in methods.

24.1.1.1 Map ( [ iterable ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let map be ? OrdinaryCreateFromConstructor(NewTarget, "%Map.prototype%", « [[MapData]] »).
  3. Set map.[[MapData]] to a new empty List.
  4. If iterable is either undefined or null, return map.
  5. Let adder be ? Get(map, "set").
  6. If IsCallable(adder) is false, throw a TypeError exception.
  7. Return ? AddEntriesFromIterable(map, iterable, adder).
Note

If the parameter iterable is present, it is expected to be an object that implements an @@iterator method that returns an iterator object that produces a two element array-like object whose first element is a value that will be used as a Map key and whose second element is the value to associate with that key.

24.1.1.2 AddEntriesFromIterable ( target, iterable, adder )

The abstract operation AddEntriesFromIterable takes arguments target (an Object), iterable (an ECMAScript language value, but not undefined or null), and adder (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion. adder will be invoked, with target as the receiver. It performs the following steps when called:

  1. Let iteratorRecord be ? GetIterator(iterable, sync).
  2. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, return target.
    3. If next is not an Object, then
      1. Let error be ThrowCompletion(a newly created TypeError object).
      2. Return ? IteratorClose(iteratorRecord, error).
    4. Let k be Completion(Get(next, "0")).
    5. IfAbruptCloseIterator(k, iteratorRecord).
    6. Let v be Completion(Get(next, "1")).
    7. IfAbruptCloseIterator(v, iteratorRecord).
    8. Let status be Completion(Call(adder, target, « k, v »)).
    9. IfAbruptCloseIterator(status, iteratorRecord).
Note

The parameter iterable is expected to be an object that implements an @@iterator method that returns an iterator object that produces a two element array-like object whose first element is a value that will be used as a Map key and whose second element is the value to associate with that key.

24.1.2 Properties of the Map Constructor

The Map constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

24.1.2.1 Map.groupBy ( items, callbackfn )

Note

callbackfn should be a function that accepts two arguments. groupBy calls callbackfn once for each element in items, in ascending order, and constructs a new Map. Each value returned by callbackfn is used as a key in the Map. For each such key, the result Map has an entry whose key is that key and whose value is an array containing all the elements for which callbackfn returned that key.

callbackfn is called with two arguments: the value of the element and the index of the element.

The return value of groupBy is a Map.

This function performs the following steps when called:

  1. Let groups be ? GroupBy(items, callbackfn, zero).
  2. Let map be ! Construct(%Map%).
  3. For each Record { [[Key]], [[Elements]] } g of groups, do
    1. Let elements be CreateArrayFromList(g.[[Elements]]).
    2. Let entry be the Record { [[Key]]: g.[[Key]], [[Value]]: elements }.
    3. Append entry to map.[[MapData]].
  4. Return map.

24.1.2.2 Map.prototype

The initial value of Map.prototype is the Map prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.1.2.3 get Map [ @@species ]

Map[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

Methods that create derived collection objects should call @@species to determine the constructor to use to create the derived objects. Subclass constructor may over-ride @@species to change the default constructor assignment.

24.1.3 Properties of the Map Prototype Object

The Map prototype object:

24.1.3.1 Map.prototype.clear ( )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. Set p.[[Key]] to empty.
    2. Set p.[[Value]] to empty.
  4. Return undefined.
Note

The existing [[MapData]] List is preserved because there may be existing Map Iterator objects that are suspended midway through iterating over that List.

24.1.3.2 Map.prototype.constructor

The initial value of Map.prototype.constructor is %Map%.

24.1.3.3 Map.prototype.delete ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, then
      1. Set p.[[Key]] to empty.
      2. Set p.[[Value]] to empty.
      3. Return true.
  4. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

24.1.3.4 Map.prototype.entries ( )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Return ? CreateMapIterator(M, key+value).

24.1.3.5 Map.prototype.forEach ( callbackfn [ , thisArg ] )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. Let entries be M.[[MapData]].
  5. Let numEntries be the number of elements in entries.
  6. Let index be 0.
  7. Repeat, while index < numEntries,
    1. Let e be entries[index].
    2. Set index to index + 1.
    3. If e.[[Key]] is not empty, then
      1. Perform ? Call(callbackfn, thisArg, « e.[[Value]], e.[[Key]], M »).
      2. NOTE: The number of elements in entries may have increased during execution of callbackfn.
      3. Set numEntries to the number of elements in entries.
  8. Return undefined.
Note

callbackfn should be a function that accepts three arguments. forEach calls callbackfn once for each key/value pair present in the Map, in key insertion order. callbackfn is called only for keys of the Map which actually exist; it is not called for keys that have been deleted from the Map.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the value of the item, the key of the item, and the Map being traversed.

forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn. Each entry of a map's [[MapData]] is only visited once. New keys added after the call to forEach begins are visited. A key will be revisited if it is deleted after it has been visited and then re-added before the forEach call completes. Keys that are deleted after the call to forEach begins and before being visited are not visited unless the key is added again before the forEach call completes.

24.1.3.6 Map.prototype.get ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, return p.[[Value]].
  4. Return undefined.

24.1.3.7 Map.prototype.has ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, return true.
  4. Return false.

24.1.3.8 Map.prototype.keys ( )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Return ? CreateMapIterator(M, key).

24.1.3.9 Map.prototype.set ( key, value )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. If p.[[Key]] is not empty and SameValueZero(p.[[Key]], key) is true, then
      1. Set p.[[Value]] to value.
      2. Return M.
  4. If key is -0𝔽, set key to +0𝔽.
  5. Let p be the Record { [[Key]]: key, [[Value]]: value }.
  6. Append p to M.[[MapData]].
  7. Return M.

24.1.3.10 get Map.prototype.size

Map.prototype.size is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. Let count be 0.
  4. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. If p.[[Key]] is not empty, set count to count + 1.
  5. Return 𝔽(count).

24.1.3.11 Map.prototype.values ( )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Return ? CreateMapIterator(M, value).

24.1.3.12 Map.prototype [ @@iterator ] ( )

The initial value of the @@iterator property is %Map.prototype.entries%, defined in 24.1.3.4.

24.1.3.13 Map.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Map".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.1.4 Properties of Map Instances

Map instances are ordinary objects that inherit properties from the Map prototype. Map instances also have a [[MapData]] internal slot.

24.1.5 Map Iterator Objects

A Map Iterator is an object, that represents a specific iteration over some specific Map instance object. There is not a named constructor for Map Iterator objects. Instead, map iterator objects are created by calling certain methods of Map instance objects.

24.1.5.1 CreateMapIterator ( map, kind )

The abstract operation CreateMapIterator takes arguments map (an ECMAScript language value) and kind (key+value, key, or value) and returns either a normal completion containing a Generator or a throw completion. It is used to create iterator objects for Map methods that return such iterators. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(map, [[MapData]]).
  2. Let closure be a new Abstract Closure with no parameters that captures map and kind and performs the following steps when called:
    1. Let entries be map.[[MapData]].
    2. Let index be 0.
    3. Let numEntries be the number of elements in entries.
    4. Repeat, while index < numEntries,
      1. Let e be entries[index].
      2. Set index to index + 1.
      3. If e.[[Key]] is not empty, then
        1. If kind is key, then
          1. Let result be e.[[Key]].
        2. Else if kind is value, then
          1. Let result be e.[[Value]].
        3. Else,
          1. Assert: kind is key+value.
          2. Let result be CreateArrayFromListe.[[Key]], e.[[Value]] »).
        4. Perform ? GeneratorYield(CreateIterResultObject(result, false)).
        5. NOTE: The number of elements in entries may have increased while execution of this abstract operation was paused by Yield.
        6. Set numEntries to the number of elements in entries.
    5. Return undefined.
  3. Return CreateIteratorFromClosure(closure, "%MapIteratorPrototype%", %MapIteratorPrototype%).

24.1.5.2 The %MapIteratorPrototype% Object

The %MapIteratorPrototype% object:

  • has properties that are inherited by all Map Iterator Objects.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %IteratorPrototype%.
  • has the following properties:

24.1.5.2.1 %MapIteratorPrototype%.next ( )

  1. Return ? GeneratorResume(this value, empty, "%MapIteratorPrototype%").

24.1.5.2.2 %MapIteratorPrototype% [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Map Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.2 Set Objects

Set objects are collections of ECMAScript language values. A distinct value may only occur once as an element of a Set's collection. Distinct values are discriminated using the SameValueZero comparison algorithm.

Set objects must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structure used in this specification is only intended to describe the required observable semantics of Set objects. It is not intended to be a viable implementation model.

24.2.1 The Set Constructor

The Set constructor:

  • is %Set%.
  • is the initial value of the "Set" property of the global object.
  • creates and initializes a new Set object when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Set behaviour must include a super call to the Set constructor to create and initialize the subclass instance with the internal state necessary to support the Set.prototype built-in methods.

24.2.1.1 Set ( [ iterable ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%Set.prototype%", « [[SetData]] »).
  3. Set set.[[SetData]] to a new empty List.
  4. If iterable is either undefined or null, return set.
  5. Let adder be ? Get(set, "add").
  6. If IsCallable(adder) is false, throw a TypeError exception.
  7. Let iteratorRecord be ? GetIterator(iterable, sync).
  8. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, return set.
    3. Let status be Completion(Call(adder, set, « next »)).
    4. IfAbruptCloseIterator(status, iteratorRecord).

24.2.2 Properties of the Set Constructor

The Set constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

24.2.2.1 Set.prototype

The initial value of Set.prototype is the Set prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.2.2.2 get Set [ @@species ]

Set[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

Methods that create derived collection objects should call @@species to determine the constructor to use to create the derived objects. Subclass constructor may over-ride @@species to change the default constructor assignment.

24.2.3 Properties of the Set Prototype Object

The Set prototype object:

24.2.3.1 Set.prototype.add ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. For each element e of S.[[SetData]], do
    1. If e is not empty and SameValueZero(e, value) is true, then
      1. Return S.
  4. If value is -0𝔽, set value to +0𝔽.
  5. Append value to S.[[SetData]].
  6. Return S.

24.2.3.2 Set.prototype.clear ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. For each element e of S.[[SetData]], do
    1. Replace the element of S.[[SetData]] whose value is e with an element whose value is empty.
  4. Return undefined.
Note

The existing [[SetData]] List is preserved because there may be existing Set Iterator objects that are suspended midway through iterating over that List.

24.2.3.3 Set.prototype.constructor

The initial value of Set.prototype.constructor is %Set%.

24.2.3.4 Set.prototype.delete ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. For each element e of S.[[SetData]], do
    1. If e is not empty and SameValueZero(e, value) is true, then
      1. Replace the element of S.[[SetData]] whose value is e with an element whose value is empty.
      2. Return true.
  4. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

24.2.3.5 Set.prototype.entries ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateSetIterator(S, key+value).
Note

For iteration purposes, a Set appears similar to a Map where each entry has the same value for its key and value.

24.2.3.6 Set.prototype.forEach ( callbackfn [ , thisArg ] )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. If IsCallable(callbackfn) is false, throw a TypeError exception.
  4. Let entries be S.[[SetData]].
  5. Let numEntries be the number of elements in entries.
  6. Let index be 0.
  7. Repeat, while index < numEntries,
    1. Let e be entries[index].
    2. Set index to index + 1.
    3. If e is not empty, then
      1. Perform ? Call(callbackfn, thisArg, « e, e, S »).
      2. NOTE: The number of elements in entries may have increased during execution of callbackfn.
      3. Set numEntries to the number of elements in entries.
  8. Return undefined.
Note

callbackfn should be a function that accepts three arguments. forEach calls callbackfn once for each value present in the Set object, in value insertion order. callbackfn is called only for values of the Set which actually exist; it is not called for keys that have been deleted from the set.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callbackfn. If it is not provided, undefined is used instead.

callbackfn is called with three arguments: the first two arguments are a value contained in the Set. The same value is passed for both arguments. The Set object being traversed is passed as the third argument.

The callbackfn is called with three arguments to be consistent with the call back functions used by forEach methods for Map and Array. For Sets, each item value is considered to be both the key and the value.

forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callbackfn.

Each value is normally visited only once. However, a value will be revisited if it is deleted after it has been visited and then re-added before the forEach call completes. Values that are deleted after the call to forEach begins and before being visited are not visited unless the value is added again before the forEach call completes. New values added after the call to forEach begins are visited.

24.2.3.7 Set.prototype.has ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. For each element e of S.[[SetData]], do
    1. If e is not empty and SameValueZero(e, value) is true, return true.
  4. Return false.

24.2.3.8 Set.prototype.keys ( )

The initial value of the "keys" property is %Set.prototype.values%, defined in 24.2.3.10.

Note

For iteration purposes, a Set appears similar to a Map where each entry has the same value for its key and value.

24.2.3.9 get Set.prototype.size

Set.prototype.size is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. Let count be 0.
  4. For each element e of S.[[SetData]], do
    1. If e is not empty, set count to count + 1.
  5. Return 𝔽(count).

24.2.3.10 Set.prototype.values ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateSetIterator(S, value).

24.2.3.11 Set.prototype [ @@iterator ] ( )

The initial value of the @@iterator property is %Set.prototype.values%, defined in 24.2.3.10.

24.2.3.12 Set.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Set".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.2.4 Properties of Set Instances

Set instances are ordinary objects that inherit properties from the Set prototype. Set instances also have a [[SetData]] internal slot.

24.2.5 Set Iterator Objects

A Set Iterator is an ordinary object, with the structure defined below, that represents a specific iteration over some specific Set instance object. There is not a named constructor for Set Iterator objects. Instead, set iterator objects are created by calling certain methods of Set instance objects.

24.2.5.1 CreateSetIterator ( set, kind )

The abstract operation CreateSetIterator takes arguments set (an ECMAScript language value) and kind (key+value or value) and returns either a normal completion containing a Generator or a throw completion. It is used to create iterator objects for Set methods that return such iterators. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(set, [[SetData]]).
  2. Let closure be a new Abstract Closure with no parameters that captures set and kind and performs the following steps when called:
    1. Let index be 0.
    2. Let entries be set.[[SetData]].
    3. Let numEntries be the number of elements in entries.
    4. Repeat, while index < numEntries,
      1. Let e be entries[index].
      2. Set index to index + 1.
      3. If e is not empty, then
        1. If kind is key+value, then
          1. Let result be CreateArrayFromListe, e »).
          2. Perform ? GeneratorYield(CreateIterResultObject(result, false)).
        2. Else,
          1. Assert: kind is value.
          2. Perform ? GeneratorYield(CreateIterResultObject(e, false)).
        3. NOTE: The number of elements in entries may have increased while execution of this abstract operation was paused by Yield.
        4. Set numEntries to the number of elements in entries.
    5. Return undefined.
  3. Return CreateIteratorFromClosure(closure, "%SetIteratorPrototype%", %SetIteratorPrototype%).

24.2.5.2 The %SetIteratorPrototype% Object

The %SetIteratorPrototype% object:

  • has properties that are inherited by all Set Iterator Objects.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %IteratorPrototype%.
  • has the following properties:

24.2.5.2.1 %SetIteratorPrototype%.next ( )

  1. Return ? GeneratorResume(this value, empty, "%SetIteratorPrototype%").

24.2.5.2.2 %SetIteratorPrototype% [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Set Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.3 WeakMap Objects

WeakMaps are collections of key/value pairs where the keys are objects and/or symbols and values may be arbitrary ECMAScript language values. A WeakMap may be queried to see if it contains a key/value pair with a specific key, but no mechanism is provided for enumerating the values it holds as keys. In certain conditions, values which are not live are removed as WeakMap keys, as described in 9.10.3.

An implementation may impose an arbitrarily determined latency between the time a key/value pair of a WeakMap becomes inaccessible and the time when the key/value pair is removed from the WeakMap. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to observe a key of a WeakMap that does not require the observer to present the observed key.

WeakMaps must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of key/value pairs in the collection. The data structure used in this specification is only intended to describe the required observable semantics of WeakMaps. It is not intended to be a viable implementation model.

Note

WeakMap and WeakSet are intended to provide mechanisms for dynamically associating state with an object or symbol in a manner that does not “leak” memory resources if, in the absence of the WeakMap or WeakSet instance, the object or symbol otherwise became inaccessible and subject to resource reclamation by the implementation's garbage collection mechanisms. This characteristic can be achieved by using an inverted per-object/symbol mapping of WeakMap or WeakSet instances to keys. Alternatively, each WeakMap or WeakSet instance may internally store its key and value data, but this approach requires coordination between the WeakMap or WeakSet implementation and the garbage collector. The following references describe mechanism that may be useful to implementations of WeakMap and WeakSet:

Barry Hayes. 1997. Ephemerons: a new finalization mechanism. In Proceedings of the 12th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA '97), A. Michael Berman (Ed.). ACM, New York, NY, USA, 176-183, http://doi.acm.org/10.1145/263698.263733.

Alexandra Barros, Roberto Ierusalimschy, Eliminating Cycles in Weak Tables. Journal of Universal Computer Science - J.UCS, vol. 14, no. 21, pp. 3481-3497, 2008, http://www.jucs.org/jucs_14_21/eliminating_cycles_in_weak

24.3.1 The WeakMap Constructor

The WeakMap constructor:

  • is %WeakMap%.
  • is the initial value of the "WeakMap" property of the global object.
  • creates and initializes a new WeakMap when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified WeakMap behaviour must include a super call to the WeakMap constructor to create and initialize the subclass instance with the internal state necessary to support the WeakMap.prototype built-in methods.

24.3.1.1 WeakMap ( [ iterable ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let map be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakMap.prototype%", « [[WeakMapData]] »).
  3. Set map.[[WeakMapData]] to a new empty List.
  4. If iterable is either undefined or null, return map.
  5. Let adder be ? Get(map, "set").
  6. If IsCallable(adder) is false, throw a TypeError exception.
  7. Return ? AddEntriesFromIterable(map, iterable, adder).
Note

If the parameter iterable is present, it is expected to be an object that implements an @@iterator method that returns an iterator object that produces a two element array-like object whose first element is a value that will be used as a WeakMap key and whose second element is the value to associate with that key.

24.3.2 Properties of the WeakMap Constructor

The WeakMap constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

24.3.2.1 WeakMap.prototype

The initial value of WeakMap.prototype is the WeakMap prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.3.3 Properties of the WeakMap Prototype Object

The WeakMap prototype object:

24.3.3.1 WeakMap.prototype.constructor

The initial value of WeakMap.prototype.constructor is %WeakMap%.

24.3.3.2 WeakMap.prototype.delete ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. If CanBeHeldWeakly(key) is false, return false.
  4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
      1. Set p.[[Key]] to empty.
      2. Set p.[[Value]] to empty.
      3. Return true.
  5. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

24.3.3.3 WeakMap.prototype.get ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. If CanBeHeldWeakly(key) is false, return undefined.
  4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
  5. Return undefined.

24.3.3.4 WeakMap.prototype.has ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. If CanBeHeldWeakly(key) is false, return false.
  4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return true.
  5. Return false.

24.3.3.5 WeakMap.prototype.set ( key, value )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. If CanBeHeldWeakly(key) is false, throw a TypeError exception.
  4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
      1. Set p.[[Value]] to value.
      2. Return M.
  5. Let p be the Record { [[Key]]: key, [[Value]]: value }.
  6. Append p to M.[[WeakMapData]].
  7. Return M.

24.3.3.6 WeakMap.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "WeakMap".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.3.4 Properties of WeakMap Instances

WeakMap instances are ordinary objects that inherit properties from the WeakMap prototype. WeakMap instances also have a [[WeakMapData]] internal slot.

24.4 WeakSet Objects

WeakSets are collections of objects and/or symbols. A distinct object or symbol may only occur once as an element of a WeakSet's collection. A WeakSet may be queried to see if it contains a specific value, but no mechanism is provided for enumerating the values it holds. In certain conditions, values which are not live are removed as WeakSet elements, as described in 9.10.3.

An implementation may impose an arbitrarily determined latency between the time a value contained in a WeakSet becomes inaccessible and the time when the value is removed from the WeakSet. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to determine if a WeakSet contains a particular value that does not require the observer to present the observed value.

WeakSets must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structure used in this specification is only intended to describe the required observable semantics of WeakSets. It is not intended to be a viable implementation model.

Note

See the NOTE in 24.3.

24.4.1 The WeakSet Constructor

The WeakSet constructor:

  • is %WeakSet%.
  • is the initial value of the "WeakSet" property of the global object.
  • creates and initializes a new WeakSet when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified WeakSet behaviour must include a super call to the WeakSet constructor to create and initialize the subclass instance with the internal state necessary to support the WeakSet.prototype built-in methods.

24.4.1.1 WeakSet ( [ iterable ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakSet.prototype%", « [[WeakSetData]] »).
  3. Set set.[[WeakSetData]] to a new empty List.
  4. If iterable is either undefined or null, return set.
  5. Let adder be ? Get(set, "add").
  6. If IsCallable(adder) is false, throw a TypeError exception.
  7. Let iteratorRecord be ? GetIterator(iterable, sync).
  8. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, return set.
    3. Let status be Completion(Call(adder, set, « next »)).
    4. IfAbruptCloseIterator(status, iteratorRecord).

24.4.2 Properties of the WeakSet Constructor

The WeakSet constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

24.4.2.1 WeakSet.prototype

The initial value of WeakSet.prototype is the WeakSet prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.4.3 Properties of the WeakSet Prototype Object

The WeakSet prototype object:

24.4.3.1 WeakSet.prototype.add ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[WeakSetData]]).
  3. If CanBeHeldWeakly(value) is false, throw a TypeError exception.
  4. For each element e of S.[[WeakSetData]], do
    1. If e is not empty and SameValue(e, value) is true, then
      1. Return S.
  5. Append value to S.[[WeakSetData]].
  6. Return S.

24.4.3.2 WeakSet.prototype.constructor

The initial value of WeakSet.prototype.constructor is %WeakSet%.

24.4.3.3 WeakSet.prototype.delete ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[WeakSetData]]).
  3. If CanBeHeldWeakly(value) is false, return false.
  4. For each element e of S.[[WeakSetData]], do
    1. If e is not empty and SameValue(e, value) is true, then
      1. Replace the element of S.[[WeakSetData]] whose value is e with an element whose value is empty.
      2. Return true.
  5. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

24.4.3.4 WeakSet.prototype.has ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[WeakSetData]]).
  3. If CanBeHeldWeakly(value) is false, return false.
  4. For each element e of S.[[WeakSetData]], do
    1. If e is not empty and SameValue(e, value) is true, return true.
  5. Return false.

24.4.3.5 WeakSet.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "WeakSet".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.4.4 Properties of WeakSet Instances

WeakSet instances are ordinary objects that inherit properties from the WeakSet prototype. WeakSet instances also have a [[WeakSetData]] internal slot.

25 Structured Data

25.1 ArrayBuffer Objects

25.1.1 Notation

The descriptions below in this section, 25.4, and 29 use the read-modify-write modification function internal data structure.

A read-modify-write modification function is a mathematical function that is notationally represented as an abstract closure that takes two Lists of byte values as arguments and returns a List of byte values. These abstract closures satisfy all of the following properties:

  • They perform all their algorithm steps atomically.
  • Their individual algorithm steps are not observable.
Note

To aid verifying that a read-modify-write modification function's algorithm steps constitute a pure, mathematical function, the following editorial conventions are recommended:

  • They do not access, directly or transitively via invoked abstract operations and abstract closures, any language or specification values except their parameters and captured values.
  • They do not return Completion Records.

25.1.2 Fixed-length and Resizable ArrayBuffer Objects

A fixed-length ArrayBuffer is an ArrayBuffer whose byte length cannot change after creation.

A resizable ArrayBuffer is an ArrayBuffer whose byte length may change after creation via calls to ArrayBuffer.prototype.resize ( newLength ).

The kind of ArrayBuffer object that is created depends on the arguments passed to ArrayBuffer ( length [ , options ] ).

25.1.3 Abstract Operations For ArrayBuffer Objects

25.1.3.1 AllocateArrayBuffer ( constructor, byteLength [ , maxByteLength ] )

The abstract operation AllocateArrayBuffer takes arguments constructor (a constructor) and byteLength (a non-negative integer) and optional argument maxByteLength (a non-negative integer or empty) and returns either a normal completion containing an ArrayBuffer or a throw completion. It is used to create an ArrayBuffer. It performs the following steps when called:

  1. Let slots be « [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferDetachKey]] ».
  2. If maxByteLength is present and maxByteLength is not empty, let allocatingResizableBuffer be true; otherwise let allocatingResizableBuffer be false.
  3. If allocatingResizableBuffer is true, then
    1. If byteLength > maxByteLength, throw a RangeError exception.
    2. Append [[ArrayBufferMaxByteLength]] to slots.
  4. Let obj be ? OrdinaryCreateFromConstructor(constructor, "%ArrayBuffer.prototype%", slots).
  5. Let block be ? CreateByteDataBlock(byteLength).
  6. Set obj.[[ArrayBufferData]] to block.
  7. Set obj.[[ArrayBufferByteLength]] to byteLength.
  8. If allocatingResizableBuffer is true, then
    1. If it is not possible to create a Data Block block consisting of maxByteLength bytes, throw a RangeError exception.
    2. NOTE: Resizable ArrayBuffers are designed to be implementable with in-place growth. Implementations may throw if, for example, virtual memory cannot be reserved up front.
    3. Set obj.[[ArrayBufferMaxByteLength]] to maxByteLength.
  9. Return obj.

25.1.3.2 ArrayBufferByteLength ( arrayBuffer, order )

The abstract operation ArrayBufferByteLength takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer) and order (seq-cst or unordered) and returns a non-negative integer. It performs the following steps when called:

  1. If IsSharedArrayBuffer(arrayBuffer) is true and arrayBuffer has an [[ArrayBufferByteLengthData]] internal slot, then
    1. Let bufferByteLengthBlock be arrayBuffer.[[ArrayBufferByteLengthData]].
    2. Let rawLength be GetRawBytesFromSharedBlock(bufferByteLengthBlock, 0, biguint64, true, order).
    3. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
    4. Return (RawBytesToNumeric(biguint64, rawLength, isLittleEndian)).
  2. Assert: IsDetachedBuffer(arrayBuffer) is false.
  3. Return arrayBuffer.[[ArrayBufferByteLength]].

25.1.3.3 ArrayBufferCopyAndDetach ( arrayBuffer, newLength, preserveResizability )

The abstract operation ArrayBufferCopyAndDetach takes arguments arrayBuffer (an ECMAScript language value), newLength (an ECMAScript language value), and preserveResizability (preserve-resizability or fixed-length) and returns either a normal completion containing an ArrayBuffer or a throw completion. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(arrayBuffer, [[ArrayBufferData]]).
  2. If IsSharedArrayBuffer(arrayBuffer) is true, throw a TypeError exception.
  3. If newLength is undefined, then
    1. Let newByteLength be arrayBuffer.[[ArrayBufferByteLength]].
  4. Else,
    1. Let newByteLength be ? ToIndex(newLength).
  5. If IsDetachedBuffer(arrayBuffer) is true, throw a TypeError exception.
  6. If preserveResizability is preserve-resizability and IsFixedLengthArrayBuffer(arrayBuffer) is false, then
    1. Let newMaxByteLength be arrayBuffer.[[ArrayBufferMaxByteLength]].
  7. Else,
    1. Let newMaxByteLength be empty.
  8. If arrayBuffer.[[ArrayBufferDetachKey]] is not undefined, throw a TypeError exception.
  9. Let newBuffer be ? AllocateArrayBuffer(%ArrayBuffer%, newByteLength, newMaxByteLength).
  10. Let copyLength be min(newByteLength, arrayBuffer.[[ArrayBufferByteLength]]).
  11. Let fromBlock be arrayBuffer.[[ArrayBufferData]].
  12. Let toBlock be newBuffer.[[ArrayBufferData]].
  13. Perform CopyDataBlockBytes(toBlock, 0, fromBlock, 0, copyLength).
  14. NOTE: Neither creation of the new Data Block nor copying from the old Data Block are observable. Implementations may implement this method as a zero-copy move or a realloc.
  15. Perform ! DetachArrayBuffer(arrayBuffer).
  16. Return newBuffer.

25.1.3.4 IsDetachedBuffer ( arrayBuffer )

The abstract operation IsDetachedBuffer takes argument arrayBuffer (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It performs the following steps when called:

  1. If arrayBuffer.[[ArrayBufferData]] is null, return true.
  2. Return false.

25.1.3.5 DetachArrayBuffer ( arrayBuffer [ , key ] )

The abstract operation DetachArrayBuffer takes argument arrayBuffer (an ArrayBuffer) and optional argument key (anything) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Assert: IsSharedArrayBuffer(arrayBuffer) is false.
  2. If key is not present, set key to undefined.
  3. If arrayBuffer.[[ArrayBufferDetachKey]] is not key, throw a TypeError exception.
  4. Set arrayBuffer.[[ArrayBufferData]] to null.
  5. Set arrayBuffer.[[ArrayBufferByteLength]] to 0.
  6. Return unused.
Note

Detaching an ArrayBuffer instance disassociates the Data Block used as its backing store from the instance and sets the byte length of the buffer to 0.

25.1.3.6 CloneArrayBuffer ( srcBuffer, srcByteOffset, srcLength )

The abstract operation CloneArrayBuffer takes arguments srcBuffer (an ArrayBuffer or a SharedArrayBuffer), srcByteOffset (a non-negative integer), and srcLength (a non-negative integer) and returns either a normal completion containing an ArrayBuffer or a throw completion. It creates a new ArrayBuffer whose data is a copy of srcBuffer's data over the range starting at srcByteOffset and continuing for srcLength bytes. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(srcBuffer) is false.
  2. Let targetBuffer be ? AllocateArrayBuffer(%ArrayBuffer%, srcLength).
  3. Let srcBlock be srcBuffer.[[ArrayBufferData]].
  4. Let targetBlock be targetBuffer.[[ArrayBufferData]].
  5. Perform CopyDataBlockBytes(targetBlock, 0, srcBlock, srcByteOffset, srcLength).
  6. Return targetBuffer.

25.1.3.7 GetArrayBufferMaxByteLengthOption ( options )

The abstract operation GetArrayBufferMaxByteLengthOption takes argument options (an ECMAScript language value) and returns either a normal completion containing either a non-negative integer or empty, or a throw completion. It performs the following steps when called:

  1. If options is not an Object, return empty.
  2. Let maxByteLength be ? Get(options, "maxByteLength").
  3. If maxByteLength is undefined, return empty.
  4. Return ? ToIndex(maxByteLength).

25.1.3.8 HostResizeArrayBuffer ( buffer, newByteLength )

The host-defined abstract operation HostResizeArrayBuffer takes arguments buffer (an ArrayBuffer) and newByteLength (a non-negative integer) and returns either a normal completion containing either handled or unhandled, or a throw completion. It gives the host an opportunity to perform implementation-defined resizing of buffer. If the host chooses not to handle resizing of buffer, it may return unhandled for the default behaviour.

The implementation of HostResizeArrayBuffer must conform to the following requirements:

  • The abstract operation does not detach buffer.
  • If the abstract operation completes normally with handled, buffer.[[ArrayBufferByteLength]] is newByteLength.

The default implementation of HostResizeArrayBuffer is to return NormalCompletion(unhandled).

25.1.3.9 IsFixedLengthArrayBuffer ( arrayBuffer )

The abstract operation IsFixedLengthArrayBuffer takes argument arrayBuffer (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It performs the following steps when called:

  1. If arrayBuffer has an [[ArrayBufferMaxByteLength]] internal slot, return false.
  2. Return true.

25.1.3.10 IsUnsignedElementType ( type )

The abstract operation IsUnsignedElementType takes argument type (a TypedArray element type) and returns a Boolean. It verifies if the argument type is an unsigned TypedArray element type. It performs the following steps when called:

  1. If type is one of uint8, uint8clamped, uint16, uint32, or biguint64, return true.
  2. Return false.

25.1.3.11 IsUnclampedIntegerElementType ( type )

The abstract operation IsUnclampedIntegerElementType takes argument type (a TypedArray element type) and returns a Boolean. It verifies if the argument type is an Integer TypedArray element type not including uint8clamped. It performs the following steps when called:

  1. If type is one of int8, uint8, int16, uint16, int32, or uint32, return true.
  2. Return false.

25.1.3.12 IsBigIntElementType ( type )

The abstract operation IsBigIntElementType takes argument type (a TypedArray element type) and returns a Boolean. It verifies if the argument type is a BigInt TypedArray element type. It performs the following steps when called:

  1. If type is either biguint64 or bigint64, return true.
  2. Return false.

25.1.3.13 IsNoTearConfiguration ( type, order )

The abstract operation IsNoTearConfiguration takes arguments type (a TypedArray element type) and order (seq-cst, unordered, or init) and returns a Boolean. It performs the following steps when called:

  1. If IsUnclampedIntegerElementType(type) is true, return true.
  2. If IsBigIntElementType(type) is true and order is neither init nor unordered, return true.
  3. Return false.

25.1.3.14 RawBytesToNumeric ( type, rawBytes, isLittleEndian )

The abstract operation RawBytesToNumeric takes arguments type (a TypedArray element type), rawBytes (a List of byte values), and isLittleEndian (a Boolean) and returns a Number or a BigInt. It performs the following steps when called:

  1. Let elementSize be the Element Size value specified in Table 71 for Element Type type.
  2. If isLittleEndian is false, reverse the order of the elements of rawBytes.
  3. If type is float32, then
    1. Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2019 binary32 value.
    2. If value is an IEEE 754-2019 binary32 NaN value, return the NaN Number value.
    3. Return the Number value that corresponds to value.
  4. If type is float64, then
    1. Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2019 binary64 value.
    2. If value is an IEEE 754-2019 binary64 NaN value, return the NaN Number value.
    3. Return the Number value that corresponds to value.
  5. If IsUnsignedElementType(type) is true, then
    1. Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of an unsigned little-endian binary number.
  6. Else,
    1. Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of a binary little-endian two's complement number of bit length elementSize × 8.
  7. If IsBigIntElementType(type) is true, return the BigInt value that corresponds to intValue.
  8. Otherwise, return the Number value that corresponds to intValue.

25.1.3.15 GetRawBytesFromSharedBlock ( block, byteIndex, type, isTypedArray, order )

The abstract operation GetRawBytesFromSharedBlock takes arguments block (a Shared Data Block), byteIndex (a non-negative integer), type (a TypedArray element type), isTypedArray (a Boolean), and order (seq-cst or unordered) and returns a List of byte values. It performs the following steps when called:

  1. Let elementSize be the Element Size value specified in Table 71 for Element Type type.
  2. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
  3. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
  4. If isTypedArray is true and IsNoTearConfiguration(type, order) is true, let noTear be true; otherwise let noTear be false.
  5. Let rawValue be a List of length elementSize whose elements are nondeterministically chosen byte values.
  6. NOTE: In implementations, rawValue is the result of a non-atomic or atomic read instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
  7. Let readEvent be ReadSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize }.
  8. Append readEvent to eventsRecord.[[EventList]].
  9. Append Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: rawValue } to execution.[[ChosenValues]].
  10. Return rawValue.

25.1.3.16 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isTypedArray, order [ , isLittleEndian ] )

The abstract operation GetValueFromBuffer takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), isTypedArray (a Boolean), and order (seq-cst or unordered) and optional argument isLittleEndian (a Boolean) and returns a Number or a BigInt. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(arrayBuffer) is false.
  2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.
  3. Let block be arrayBuffer.[[ArrayBufferData]].
  4. Let elementSize be the Element Size value specified in Table 71 for Element Type type.
  5. If IsSharedArrayBuffer(arrayBuffer) is true, then
    1. Assert: block is a Shared Data Block.
    2. Let rawValue be GetRawBytesFromSharedBlock(block, byteIndex, type, isTypedArray, order).
  6. Else,
    1. Let rawValue be a List whose elements are bytes from block at indices in the interval from byteIndex (inclusive) to byteIndex + elementSize (exclusive).
  7. Assert: The number of elements in rawValue is elementSize.
  8. If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  9. Return RawBytesToNumeric(type, rawValue, isLittleEndian).

25.1.3.17 NumericToRawBytes ( type, value, isLittleEndian )

The abstract operation NumericToRawBytes takes arguments type (a TypedArray element type), value (a Number or a BigInt), and isLittleEndian (a Boolean) and returns a List of byte values. It performs the following steps when called:

  1. If type is float32, then
    1. Let rawBytes be a List whose elements are the 4 bytes that are the result of converting value to IEEE 754-2019 binary32 format using roundTiesToEven mode. The bytes are arranged in little endian order. If value is NaN, rawBytes may be set to any implementation chosen IEEE 754-2019 binary32 format Not-a-Number encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value.
  2. Else if type is float64, then
    1. Let rawBytes be a List whose elements are the 8 bytes that are the IEEE 754-2019 binary64 format encoding of value. The bytes are arranged in little endian order. If value is NaN, rawBytes may be set to any implementation chosen IEEE 754-2019 binary64 format Not-a-Number encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value.
  3. Else,
    1. Let n be the Element Size value specified in Table 71 for Element Type type.
    2. Let convOp be the abstract operation named in the Conversion Operation column in Table 71 for Element Type type.
    3. Let intValue be (convOp(value)).
    4. If intValue ≥ 0, then
      1. Let rawBytes be a List whose elements are the n-byte binary encoding of intValue. The bytes are ordered in little endian order.
    5. Else,
      1. Let rawBytes be a List whose elements are the n-byte binary two's complement encoding of intValue. The bytes are ordered in little endian order.
  4. If isLittleEndian is false, reverse the order of the elements of rawBytes.
  5. Return rawBytes.

25.1.3.18 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order [ , isLittleEndian ] )

The abstract operation SetValueInBuffer takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), value (a Number or a BigInt), isTypedArray (a Boolean), and order (seq-cst, unordered, or init) and optional argument isLittleEndian (a Boolean) and returns unused. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(arrayBuffer) is false.
  2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.
  3. Assert: value is a BigInt if IsBigIntElementType(type) is true; otherwise, value is a Number.
  4. Let block be arrayBuffer.[[ArrayBufferData]].
  5. Let elementSize be the Element Size value specified in Table 71 for Element Type type.
  6. If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  7. Let rawBytes be NumericToRawBytes(type, value, isLittleEndian).
  8. If IsSharedArrayBuffer(arrayBuffer) is true, then
    1. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
    2. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
    3. If isTypedArray is true and IsNoTearConfiguration(type, order) is true, let noTear be true; otherwise let noTear be false.
    4. Append WriteSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes } to eventsRecord.[[EventList]].
  9. Else,
    1. Store the individual bytes of rawBytes into block, starting at block[byteIndex].
  10. Return unused.

25.1.3.19 GetModifySetValueInBuffer ( arrayBuffer, byteIndex, type, value, op )

The abstract operation GetModifySetValueInBuffer takes arguments arrayBuffer (an ArrayBuffer or a SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), value (a Number or a BigInt), and op (a read-modify-write modification function) and returns a Number or a BigInt. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(arrayBuffer) is false.
  2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.
  3. Assert: value is a BigInt if IsBigIntElementType(type) is true; otherwise, value is a Number.
  4. Let block be arrayBuffer.[[ArrayBufferData]].
  5. Let elementSize be the Element Size value specified in Table 71 for Element Type type.
  6. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  7. Let rawBytes be NumericToRawBytes(type, value, isLittleEndian).
  8. If IsSharedArrayBuffer(arrayBuffer) is true, then
    1. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
    2. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
    3. Let rawBytesRead be a List of length elementSize whose elements are nondeterministically chosen byte values.
    4. NOTE: In implementations, rawBytesRead is the result of a load-link, of a load-exclusive, or of an operand of a read-modify-write instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
    5. Let rmwEvent be ReadModifyWriteSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes, [[ModifyOp]]: op }.
    6. Append rmwEvent to eventsRecord.[[EventList]].
    7. Append Chosen Value Record { [[Event]]: rmwEvent, [[ChosenValue]]: rawBytesRead } to execution.[[ChosenValues]].
  9. Else,
    1. Let rawBytesRead be a List of length elementSize whose elements are the sequence of elementSize bytes starting with block[byteIndex].
    2. Let rawBytesModified be op(rawBytesRead, rawBytes).
    3. Store the individual bytes of rawBytesModified into block, starting at block[byteIndex].
  10. Return RawBytesToNumeric(type, rawBytesRead, isLittleEndian).

25.1.4 The ArrayBuffer Constructor

The ArrayBuffer constructor:

  • is %ArrayBuffer%.
  • is the initial value of the "ArrayBuffer" property of the global object.
  • creates and initializes a new ArrayBuffer when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified ArrayBuffer behaviour must include a super call to the ArrayBuffer constructor to create and initialize subclass instances with the internal state necessary to support the ArrayBuffer.prototype built-in methods.

25.1.4.1 ArrayBuffer ( length [ , options ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let byteLength be ? ToIndex(length).
  3. Let requestedMaxByteLength be ? GetArrayBufferMaxByteLengthOption(options).
  4. Return ? AllocateArrayBuffer(NewTarget, byteLength, requestedMaxByteLength).

25.1.5 Properties of the ArrayBuffer Constructor

The ArrayBuffer constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

25.1.5.1 ArrayBuffer.isView ( arg )

This function performs the following steps when called:

  1. If arg is not an Object, return false.
  2. If arg has a [[ViewedArrayBuffer]] internal slot, return true.
  3. Return false.

25.1.5.2 ArrayBuffer.prototype

The initial value of ArrayBuffer.prototype is the ArrayBuffer prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

25.1.5.3 get ArrayBuffer [ @@species ]

ArrayBuffer[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

ArrayBuffer.prototype.slice ( start, end ) normally uses its this value's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour for the ArrayBuffer.prototype.slice ( start, end ) method by redefining its @@species property.

25.1.6 Properties of the ArrayBuffer Prototype Object

The ArrayBuffer prototype object:

  • is %ArrayBuffer.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have an [[ArrayBufferData]] or [[ArrayBufferByteLength]] internal slot.

25.1.6.1 get ArrayBuffer.prototype.byteLength

ArrayBuffer.prototype.byteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. If IsDetachedBuffer(O) is true, return +0𝔽.
  5. Let length be O.[[ArrayBufferByteLength]].
  6. Return 𝔽(length).

25.1.6.2 ArrayBuffer.prototype.constructor

The initial value of ArrayBuffer.prototype.constructor is %ArrayBuffer%.

25.1.6.3 get ArrayBuffer.prototype.detached

ArrayBuffer.prototype.detached is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. Return IsDetachedBuffer(O).

25.1.6.4 get ArrayBuffer.prototype.maxByteLength

ArrayBuffer.prototype.maxByteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. If IsDetachedBuffer(O) is true, return +0𝔽.
  5. If IsFixedLengthArrayBuffer(O) is true, then
    1. Let length be O.[[ArrayBufferByteLength]].
  6. Else,
    1. Let length be O.[[ArrayBufferMaxByteLength]].
  7. Return 𝔽(length).

25.1.6.5 get ArrayBuffer.prototype.resizable

ArrayBuffer.prototype.resizable is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. If IsFixedLengthArrayBuffer(O) is false, return true; otherwise return false.

25.1.6.6 ArrayBuffer.prototype.resize ( newLength )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferMaxByteLength]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. Let newByteLength be ? ToIndex(newLength).
  5. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  6. If newByteLength > O.[[ArrayBufferMaxByteLength]], throw a RangeError exception.
  7. Let hostHandled be ? HostResizeArrayBuffer(O, newByteLength).
  8. If hostHandled is handled, return undefined.
  9. Let oldBlock be O.[[ArrayBufferData]].
  10. Let newBlock be ? CreateByteDataBlock(newByteLength).
  11. Let copyLength be min(newByteLength, O.[[ArrayBufferByteLength]]).
  12. Perform CopyDataBlockBytes(newBlock, 0, oldBlock, 0, copyLength).
  13. NOTE: Neither creation of the new Data Block nor copying from the old Data Block are observable. Implementations may implement this method as in-place growth or shrinkage.
  14. Set O.[[ArrayBufferData]] to newBlock.
  15. Set O.[[ArrayBufferByteLength]] to newByteLength.
  16. Return undefined.

25.1.6.7 ArrayBuffer.prototype.slice ( start, end )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  5. Let len be O.[[ArrayBufferByteLength]].
  6. Let relativeStart be ? ToIntegerOrInfinity(start).
  7. If relativeStart = -∞, let first be 0.
  8. Else if relativeStart < 0, let first be max(len + relativeStart, 0).
  9. Else, let first be min(relativeStart, len).
  10. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  11. If relativeEnd = -∞, let final be 0.
  12. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
  13. Else, let final be min(relativeEnd, len).
  14. Let newLen be max(final - first, 0).
  15. Let ctor be ? SpeciesConstructor(O, %ArrayBuffer%).
  16. Let new be ? Construct(ctor, « 𝔽(newLen) »).
  17. Perform ? RequireInternalSlot(new, [[ArrayBufferData]]).
  18. If IsSharedArrayBuffer(new) is true, throw a TypeError exception.
  19. If IsDetachedBuffer(new) is true, throw a TypeError exception.
  20. If SameValue(new, O) is true, throw a TypeError exception.
  21. If new.[[ArrayBufferByteLength]] < newLen, throw a TypeError exception.
  22. NOTE: Side-effects of the above steps may have detached or resized O.
  23. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  24. Let fromBuf be O.[[ArrayBufferData]].
  25. Let toBuf be new.[[ArrayBufferData]].
  26. Let currentLen be O.[[ArrayBufferByteLength]].
  27. If first < currentLen, then
    1. Let count be min(newLen, currentLen - first).
    2. Perform CopyDataBlockBytes(toBuf, 0, fromBuf, first, count).
  28. Return new.

25.1.6.8 ArrayBuffer.prototype.transfer ( [ newLength ] )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Return ? ArrayBufferCopyAndDetach(O, newLength, preserve-resizability).

25.1.6.9 ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Return ? ArrayBufferCopyAndDetach(O, newLength, fixed-length).

25.1.6.10 ArrayBuffer.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "ArrayBuffer".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.1.7 Properties of ArrayBuffer Instances

ArrayBuffer instances inherit properties from the ArrayBuffer prototype object. ArrayBuffer instances each have an [[ArrayBufferData]] internal slot, an [[ArrayBufferByteLength]] internal slot, and an [[ArrayBufferDetachKey]] internal slot. ArrayBuffer instances which are resizable each have an [[ArrayBufferMaxByteLength]] internal slot.

ArrayBuffer instances whose [[ArrayBufferData]] is null are considered to be detached and all operators to access or modify data contained in the ArrayBuffer instance will fail.

ArrayBuffer instances whose [[ArrayBufferDetachKey]] is set to a value other than undefined need to have all DetachArrayBuffer calls passing that same "detach key" as an argument, otherwise a TypeError will result. This internal slot is only ever set by certain embedding environments, not by algorithms in this specification.

25.1.8 Resizable ArrayBuffer Guidelines

Note 1

The following are guidelines for ECMAScript programmers working with resizable ArrayBuffer.

We recommend that programs be tested in their deployment environments where possible. The amount of available physical memory differs greatly between hardware devices. Similarly, virtual memory subsystems also differ greatly between hardware devices as well as operating systems. An application that runs without out-of-memory errors on a 64-bit desktop web browser could run out of memory on a 32-bit mobile web browser.

When choosing a value for the "maxByteLength" option for resizable ArrayBuffer, we recommend that the smallest possible size for the application be chosen. We recommend that "maxByteLength" does not exceed 1,073,741,824 (230 bytes or 1GiB).

Please note that successfully constructing a resizable ArrayBuffer for a particular maximum size does not guarantee that future resizes will succeed.

Note 2

The following are guidelines for ECMAScript implementers implementing resizable ArrayBuffer.

Resizable ArrayBuffer can be implemented as copying upon resize, as in-place growth via reserving virtual memory up front, or as a combination of both for different values of the constructor's "maxByteLength" option.

If a host is multi-tenanted (i.e. it runs many ECMAScript applications simultaneously), such as a web browser, and its implementations choose to implement in-place growth by reserving virtual memory, we recommend that both 32-bit and 64-bit implementations throw for values of "maxByteLength" ≥ 1GiB to 1.5GiB. This is to reduce the likelihood a single application can exhaust the virtual memory address space and to reduce interoperability risk.

If a host does not have virtual memory, such as those running on embedded devices without an MMU, or if a host only implements resizing by copying, it may accept any Number value for the "maxByteLength" option. However, we recommend a RangeError be thrown if a memory block of the requested size can never be allocated. For example, if the requested size is greater than the maximium amount of usable memory on the device.

25.2 SharedArrayBuffer Objects

25.2.1 Fixed-length and Growable SharedArrayBuffer Objects

A fixed-length SharedArrayBuffer is a SharedArrayBuffer whose byte length cannot change after creation.

A growable SharedArrayBuffer is a SharedArrayBuffer whose byte length may increase after creation via calls to SharedArrayBuffer.prototype.grow ( newLength ).

The kind of SharedArrayBuffer object that is created depends on the arguments passed to SharedArrayBuffer ( length [ , options ] ).

25.2.2 Abstract Operations for SharedArrayBuffer Objects

25.2.2.1 AllocateSharedArrayBuffer ( constructor, byteLength [ , maxByteLength ] )

The abstract operation AllocateSharedArrayBuffer takes arguments constructor (a constructor) and byteLength (a non-negative integer) and optional argument maxByteLength (a non-negative integer or empty) and returns either a normal completion containing a SharedArrayBuffer or a throw completion. It is used to create a SharedArrayBuffer. It performs the following steps when called:

  1. Let slots be « [[ArrayBufferData]] ».
  2. If maxByteLength is present and maxByteLength is not empty, let allocatingGrowableBuffer be true; otherwise let allocatingGrowableBuffer be false.
  3. If allocatingGrowableBuffer is true, then
    1. If byteLength > maxByteLength, throw a RangeError exception.
    2. Append [[ArrayBufferByteLengthData]] and [[ArrayBufferMaxByteLength]] to slots.
  4. Else,
    1. Append [[ArrayBufferByteLength]] to slots.
  5. Let obj be ? OrdinaryCreateFromConstructor(constructor, "%SharedArrayBuffer.prototype%", slots).
  6. If allocatingGrowableBuffer is true, let allocLength be maxByteLength; otherwise let allocLength be byteLength.
  7. Let block be ? CreateSharedByteDataBlock(allocLength).
  8. Set obj.[[ArrayBufferData]] to block.
  9. If allocatingGrowableBuffer is true, then
    1. Assert: byteLengthmaxByteLength.
    2. Let byteLengthBlock be ? CreateSharedByteDataBlock(8).
    3. Perform SetValueInBuffer(byteLengthBlock, 0, biguint64, (byteLength), true, seq-cst).
    4. Set obj.[[ArrayBufferByteLengthData]] to byteLengthBlock.
    5. Set obj.[[ArrayBufferMaxByteLength]] to maxByteLength.
  10. Else,
    1. Set obj.[[ArrayBufferByteLength]] to byteLength.
  11. Return obj.

25.2.2.2 IsSharedArrayBuffer ( obj )

The abstract operation IsSharedArrayBuffer takes argument obj (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It tests whether an object is an ArrayBuffer, a SharedArrayBuffer, or a subtype of either. It performs the following steps when called:

  1. Let bufferData be obj.[[ArrayBufferData]].
  2. If bufferData is null, return false.
  3. If bufferData is a Data Block, return false.
  4. Assert: bufferData is a Shared Data Block.
  5. Return true.

25.2.2.3 HostGrowSharedArrayBuffer ( buffer, newByteLength )

The host-defined abstract operation HostGrowSharedArrayBuffer takes arguments buffer (a SharedArrayBuffer) and newByteLength (a non-negative integer) and returns either a normal completion containing either handled or unhandled, or a throw completion. It gives the host an opportunity to perform implementation-defined growing of buffer. If the host chooses not to handle growing of buffer, it may return unhandled for the default behaviour.

The implementation of HostGrowSharedArrayBuffer must conform to the following requirements:

  • If the abstract operation does not complete normally with unhandled, and newByteLength < the current byte length of the buffer or newByteLength > buffer.[[ArrayBufferMaxByteLength]], throw a RangeError exception.
  • Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record. If the abstract operation completes normally with handled, a WriteSharedMemory or ReadModifyWriteSharedMemory event whose [[Order]] is seq-cst, [[Payload]] is NumericToRawBytes(biguint64, newByteLength, isLittleEndian), [[Block]] is buffer.[[ArrayBufferByteLengthData]], [[ByteIndex]] is 0, and [[ElementSize]] is 8 is added to the surrounding agent's candidate execution such that racing calls to SharedArrayBuffer.prototype.grow are not "lost", i.e. silently do nothing.
Note

The second requirement above is intentionally vague about how or when the current byte length of buffer is read. Because the byte length must be updated via an atomic read-modify-write operation on the underlying hardware, architectures that use load-link/store-conditional or load-exclusive/store-exclusive instruction pairs may wish to keep the paired instructions close in the instruction stream. As such, SharedArrayBuffer.prototype.grow itself does not perform bounds checking on newByteLength before calling HostGrowSharedArrayBuffer, nor is there a requirement on when the current byte length is read.

This is in contrast with HostResizeArrayBuffer, which is guaranteed that the value of newByteLength is ≥ 0 and ≤ buffer.[[ArrayBufferMaxByteLength]].

The default implementation of HostGrowSharedArrayBuffer is to return NormalCompletion(unhandled).

25.2.3 The SharedArrayBuffer Constructor

The SharedArrayBuffer constructor:

  • is %SharedArrayBuffer%.
  • is the initial value of the "SharedArrayBuffer" property of the global object, if that property is present (see below).
  • creates and initializes a new SharedArrayBuffer when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified SharedArrayBuffer behaviour must include a super call to the SharedArrayBuffer constructor to create and initialize subclass instances with the internal state necessary to support the SharedArrayBuffer.prototype built-in methods.

Whenever a host does not provide concurrent access to SharedArrayBuffers it may omit the "SharedArrayBuffer" property of the global object.

Note

Unlike an ArrayBuffer, a SharedArrayBuffer cannot become detached, and its internal [[ArrayBufferData]] slot is never null.

25.2.3.1 SharedArrayBuffer ( length [ , options ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let byteLength be ? ToIndex(length).
  3. Let requestedMaxByteLength be ? GetArrayBufferMaxByteLengthOption(options).
  4. Return ? AllocateSharedArrayBuffer(NewTarget, byteLength, requestedMaxByteLength).

25.2.4 Properties of the SharedArrayBuffer Constructor

The SharedArrayBuffer constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

25.2.4.1 SharedArrayBuffer.prototype

The initial value of SharedArrayBuffer.prototype is the SharedArrayBuffer prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

25.2.4.2 get SharedArrayBuffer [ @@species ]

SharedArrayBuffer[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

25.2.5 Properties of the SharedArrayBuffer Prototype Object

The SharedArrayBuffer prototype object:

  • is %SharedArrayBuffer.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have an [[ArrayBufferData]] or [[ArrayBufferByteLength]] internal slot.

25.2.5.1 get SharedArrayBuffer.prototype.byteLength

SharedArrayBuffer.prototype.byteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  4. Let length be ArrayBufferByteLength(O, seq-cst).
  5. Return 𝔽(length).

25.2.5.2 SharedArrayBuffer.prototype.constructor

The initial value of SharedArrayBuffer.prototype.constructor is %SharedArrayBuffer%.

25.2.5.3 SharedArrayBuffer.prototype.grow ( newLength )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferMaxByteLength]]).
  3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  4. Let newByteLength be ? ToIndex(newLength).
  5. Let hostHandled be ? HostGrowSharedArrayBuffer(O, newByteLength).
  6. If hostHandled is handled, return undefined.
  7. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  8. Let byteLengthBlock be O.[[ArrayBufferByteLengthData]].
  9. Let currentByteLengthRawBytes be GetRawBytesFromSharedBlock(byteLengthBlock, 0, biguint64, true, seq-cst).
  10. Let newByteLengthRawBytes be NumericToRawBytes(biguint64, (newByteLength), isLittleEndian).
  11. Repeat,
    1. NOTE: This is a compare-and-exchange loop to ensure that parallel, racing grows of the same buffer are totally ordered, are not lost, and do not silently do nothing. The loop exits if it was able to attempt to grow uncontended.
    2. Let currentByteLength be (RawBytesToNumeric(biguint64, currentByteLengthRawBytes, isLittleEndian)).
    3. If newByteLength = currentByteLength, return undefined.
    4. If newByteLength < currentByteLength or newByteLength > O.[[ArrayBufferMaxByteLength]], throw a RangeError exception.
    5. Let byteLengthDelta be newByteLength - currentByteLength.
    6. If it is impossible to create a new Shared Data Block value consisting of byteLengthDelta bytes, throw a RangeError exception.
    7. NOTE: No new Shared Data Block is constructed and used here. The observable behaviour of growable SharedArrayBuffers is specified by allocating a max-sized Shared Data Block at construction time, and this step captures the requirement that implementations that run out of memory must throw a RangeError.
    8. Let readByteLengthRawBytes be AtomicCompareExchangeInSharedBlock(byteLengthBlock, 0, 8, currentByteLengthRawBytes, newByteLengthRawBytes).
    9. If ByteListEqual(readByteLengthRawBytes, currentByteLengthRawBytes) is true, return undefined.
    10. Set currentByteLengthRawBytes to readByteLengthRawBytes.
Note

Spurious failures of the compare-exchange to update the length are prohibited. If the bounds checking for the new length passes and the implementation is not out of memory, a ReadModifyWriteSharedMemory event (i.e. a successful compare-exchange) is always added into the candidate execution.

Parallel calls to SharedArrayBuffer.prototype.grow are totally ordered. For example, consider two racing calls: sab.grow(10) and sab.grow(20). One of the two calls is guaranteed to win the race. The call to sab.grow(10) will never shrink sab even if sab.grow(20) happened first; in that case it will instead throw a RangeError.

25.2.5.4 get SharedArrayBuffer.prototype.growable

SharedArrayBuffer.prototype.growable is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  4. If IsFixedLengthArrayBuffer(O) is false, return true; otherwise return false.

25.2.5.5 get SharedArrayBuffer.prototype.maxByteLength

SharedArrayBuffer.prototype.maxByteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  4. If IsFixedLengthArrayBuffer(O) is true, then
    1. Let length be O.[[ArrayBufferByteLength]].
  5. Else,
    1. Let length be O.[[ArrayBufferMaxByteLength]].
  6. Return 𝔽(length).

25.2.5.6 SharedArrayBuffer.prototype.slice ( start, end )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  4. Let len be ArrayBufferByteLength(O, seq-cst).
  5. Let relativeStart be ? ToIntegerOrInfinity(start).
  6. If relativeStart = -∞, let first be 0.
  7. Else if relativeStart < 0, let first be max(len + relativeStart, 0).
  8. Else, let first be min(relativeStart, len).
  9. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  10. If relativeEnd = -∞, let final be 0.
  11. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
  12. Else, let final be min(relativeEnd, len).
  13. Let newLen be max(final - first, 0).
  14. Let ctor be ? SpeciesConstructor(O, %SharedArrayBuffer%).
  15. Let new be ? Construct(ctor, « 𝔽(newLen) »).
  16. Perform ? RequireInternalSlot(new, [[ArrayBufferData]]).
  17. If IsSharedArrayBuffer(new) is false, throw a TypeError exception.
  18. If new.[[ArrayBufferData]] is O.[[ArrayBufferData]], throw a TypeError exception.
  19. If ArrayBufferByteLength(new, seq-cst) < newLen, throw a TypeError exception.
  20. Let fromBuf be O.[[ArrayBufferData]].
  21. Let toBuf be new.[[ArrayBufferData]].
  22. Perform CopyDataBlockBytes(toBuf, 0, fromBuf, first, newLen).
  23. Return new.

25.2.5.7 SharedArrayBuffer.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "SharedArrayBuffer".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.6 Properties of SharedArrayBuffer Instances

SharedArrayBuffer instances inherit properties from the SharedArrayBuffer prototype object. SharedArrayBuffer instances each have an [[ArrayBufferData]] internal slot. SharedArrayBuffer instances which are not growable each have an [[ArrayBufferByteLength]] internal slot. SharedArrayBuffer instances which are growable each have an [[ArrayBufferByteLengthData]] internal slot and an [[ArrayBufferMaxByteLength]] internal slot.

Note

SharedArrayBuffer instances, unlike ArrayBuffer instances, are never detached.

25.2.7 Growable SharedArrayBuffer Guidelines

Note 1

The following are guidelines for ECMAScript programmers working with growable SharedArrayBuffer.

We recommend that programs be tested in their deployment environments where possible. The amount of available physical memory differ greatly between hardware devices. Similarly, virtual memory subsystems also differ greatly between hardware devices as well as operating systems. An application that runs without out-of-memory errors on a 64-bit desktop web browser could run out of memory on a 32-bit mobile web browser.

When choosing a value for the "maxByteLength" option for growable SharedArrayBuffer, we recommend that the smallest possible size for the application be chosen. We recommend that "maxByteLength" does not exceed 1073741824, or 1GiB.

Please note that successfully constructing a growable SharedArrayBuffer for a particular maximum size does not guarantee that future grows will succeed.

Not all loads of a growable SharedArrayBuffer's length are synchronizing seq-cst loads. Loads of the length that are for bounds-checking of an integer-indexed property access, e.g. u8[idx], are not synchronizing. In general, in the absence of explicit synchronization, one property access being in-bound does not imply a subsequent property access in the same agent is also in-bound. In contrast, explicit loads of the length via the length and byteLength getters on SharedArrayBuffer, %TypedArray%.prototype, and DataView.prototype are synchronizing. Loads of the length that are performed by built-in methods to check if a TypedArray is entirely out-of-bounds are also synchronizing.

Note 2

The following are guidelines for ECMAScript implementers implementing growable SharedArrayBuffer.

We recommend growable SharedArrayBuffer be implemented as in-place growth via reserving virtual memory up front.

Because grow operations can happen in parallel with memory accesses on a growable SharedArrayBuffer, the constraints of the memory model require that even unordered accesses do not "tear" (bits of their values will not be mixed). In practice, this means the underlying data block of a growable SharedArrayBuffer cannot be grown by being copied without stopping the world. We do not recommend stopping the world as an implementation strategy because it introduces a serialization point and is slow.

Grown memory must appear zeroed from the moment of its creation, including to any racy accesses in parallel. This can be accomplished via zero-filled-on-demand virtual memory pages, or careful synchronization if manually zeroing memory.

Integer-indexed property access on TypedArray views of growable SharedArrayBuffers is intended to be optimizable similarly to access on TypedArray views of non-growable SharedArrayBuffers, because integer-indexed property loads on are not synchronizing on the underlying buffer's length (see programmer guidelines above). For example, bounds checks for property accesses may still be hoisted out of loops.

In practice it is difficult to implement growable SharedArrayBuffer by copying on hosts that do not have virtual memory, such as those running on embedded devices without an MMU. Memory usage behaviour of growable SharedArrayBuffers on such hosts may significantly differ from that of hosts with virtual memory. Such hosts should clearly communicate memory usage expectations to users.

25.3 DataView Objects

25.3.1 Abstract Operations For DataView Objects

25.3.1.1 DataView With Buffer Witness Records

A DataView With Buffer Witness Record is a Record value used to encapsulate a DataView along with a cached byte length of the viewed buffer. It is used to help ensure there is a single shared memory read event of the byte length data block when the viewed buffer is a growable SharedArrayBuffers.

DataView With Buffer Witness Records have the fields listed in Table 72.

Table 72: DataView With Buffer Witness Record Fields
Field Name Value Meaning
[[Object]] a DataView The DataView object whose buffer's byte length is loaded.
[[CachedBufferByteLength]] a non-negative integer or detached The byte length of the object's [[ViewedArrayBuffer]] when the Record was created.

25.3.1.2 MakeDataViewWithBufferWitnessRecord ( obj, order )

The abstract operation MakeDataViewWithBufferWitnessRecord takes arguments obj (a DataView) and order (seq-cst or unordered) and returns a DataView With Buffer Witness Record. It performs the following steps when called:

  1. Let buffer be obj.[[ViewedArrayBuffer]].
  2. If IsDetachedBuffer(buffer) is true, then
    1. Let byteLength be detached.
  3. Else,
    1. Let byteLength be ArrayBufferByteLength(buffer, order).
  4. Return the DataView With Buffer Witness Record { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength }.

25.3.1.3 GetViewByteLength ( viewRecord )

The abstract operation GetViewByteLength takes argument viewRecord (a DataView With Buffer Witness Record) and returns a non-negative integer. It performs the following steps when called:

  1. Assert: IsViewOutOfBounds(viewRecord) is false.
  2. Let view be viewRecord.[[Object]].
  3. If view.[[ByteLength]] is not auto, return view.[[ByteLength]].
  4. Assert: IsFixedLengthArrayBuffer(view.[[ViewedArrayBuffer]]) is false.
  5. Let byteOffset be view.[[ByteOffset]].
  6. Let byteLength be viewRecord.[[CachedBufferByteLength]].
  7. Assert: byteLength is not detached.
  8. Return byteLength - byteOffset.

25.3.1.4 IsViewOutOfBounds ( viewRecord )

The abstract operation IsViewOutOfBounds takes argument viewRecord (a DataView With Buffer Witness Record) and returns a Boolean. It performs the following steps when called:

  1. Let view be viewRecord.[[Object]].
  2. Let bufferByteLength be viewRecord.[[CachedBufferByteLength]].
  3. Assert: IsDetachedBuffer(view.[[ViewedArrayBuffer]]) is true if and only if bufferByteLength is detached.
  4. If bufferByteLength is detached, return true.
  5. Let byteOffsetStart be view.[[ByteOffset]].
  6. If view.[[ByteLength]] is auto, then
    1. Let byteOffsetEnd be bufferByteLength.
  7. Else,
    1. Let byteOffsetEnd be byteOffsetStart + view.[[ByteLength]].
  8. If byteOffsetStart > bufferByteLength or byteOffsetEnd > bufferByteLength, return true.
  9. NOTE: 0-length DataViews are not considered out-of-bounds.
  10. Return false.

25.3.1.5 GetViewValue ( view, requestIndex, isLittleEndian, type )

The abstract operation GetViewValue takes arguments view (an ECMAScript language value), requestIndex (an ECMAScript language value), isLittleEndian (an ECMAScript language value), and type (a TypedArray element type) and returns either a normal completion containing either a Number or a BigInt, or a throw completion. It is used by functions on DataView instances to retrieve values from the view's buffer. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(view, [[DataView]]).
  2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
  3. Let getIndex be ? ToIndex(requestIndex).
  4. Set isLittleEndian to ToBoolean(isLittleEndian).
  5. Let viewOffset be view.[[ByteOffset]].
  6. Let viewRecord be MakeDataViewWithBufferWitnessRecord(view, unordered).
  7. NOTE: Bounds checking is not a synchronizing operation when view's backing buffer is a growable SharedArrayBuffer.
  8. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
  9. Let viewSize be GetViewByteLength(viewRecord).
  10. Let elementSize be the Element Size value specified in Table 71 for Element Type type.
  11. If getIndex + elementSize > viewSize, throw a RangeError exception.
  12. Let bufferIndex be getIndex + viewOffset.
  13. Return GetValueFromBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, false, unordered, isLittleEndian).

25.3.1.6 SetViewValue ( view, requestIndex, isLittleEndian, type, value )

The abstract operation SetViewValue takes arguments view (an ECMAScript language value), requestIndex (an ECMAScript language value), isLittleEndian (an ECMAScript language value), type (a TypedArray element type), and value (an ECMAScript language value) and returns either a normal completion containing undefined or a throw completion. It is used by functions on DataView instances to store values into the view's buffer. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(view, [[DataView]]).
  2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
  3. Let getIndex be ? ToIndex(requestIndex).
  4. If IsBigIntElementType(type) is true, let numberValue be ? ToBigInt(value).
  5. Otherwise, let numberValue be ? ToNumber(value).
  6. Set isLittleEndian to ToBoolean(isLittleEndian).
  7. Let viewOffset be view.[[ByteOffset]].
  8. Let viewRecord be MakeDataViewWithBufferWitnessRecord(view, unordered).
  9. NOTE: Bounds checking is not a synchronizing operation when view's backing buffer is a growable SharedArrayBuffer.
  10. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
  11. Let viewSize be GetViewByteLength(viewRecord).
  12. Let elementSize be the Element Size value specified in Table 71 for Element Type type.
  13. If getIndex + elementSize > viewSize, throw a RangeError exception.
  14. Let bufferIndex be getIndex + viewOffset.
  15. Perform SetValueInBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, numberValue, false, unordered, isLittleEndian).
  16. Return undefined.

25.3.2 The DataView Constructor

The DataView constructor:

  • is %DataView%.
  • is the initial value of the "DataView" property of the global object.
  • creates and initializes a new DataView when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified DataView behaviour must include a super call to the DataView constructor to create and initialize subclass instances with the internal state necessary to support the DataView.prototype built-in methods.

25.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Perform ? RequireInternalSlot(buffer, [[ArrayBufferData]]).
  3. Let offset be ? ToIndex(byteOffset).
  4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  5. Let bufferByteLength be ArrayBufferByteLength(buffer, seq-cst).
  6. If offset > bufferByteLength, throw a RangeError exception.
  7. Let bufferIsFixedLength be IsFixedLengthArrayBuffer(buffer).
  8. If byteLength is undefined, then
    1. If bufferIsFixedLength is true, then
      1. Let viewByteLength be bufferByteLength - offset.
    2. Else,
      1. Let viewByteLength be auto.
  9. Else,
    1. Let viewByteLength be ? ToIndex(byteLength).
    2. If offset + viewByteLength > bufferByteLength, throw a RangeError exception.
  10. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%DataView.prototype%", « [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] »).
  11. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  12. Set bufferByteLength to ArrayBufferByteLength(buffer, seq-cst).
  13. If offset > bufferByteLength, throw a RangeError exception.
  14. If byteLength is not undefined, then
    1. If offset + viewByteLength > bufferByteLength, throw a RangeError exception.
  15. Set O.[[ViewedArrayBuffer]] to buffer.
  16. Set O.[[ByteLength]] to viewByteLength.
  17. Set O.[[ByteOffset]] to offset.
  18. Return O.

25.3.3 Properties of the DataView Constructor

The DataView constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

25.3.3.1 DataView.prototype

The initial value of DataView.prototype is the DataView prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

25.3.4 Properties of the DataView Prototype Object

The DataView prototype object:

  • is %DataView.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have a [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], or [[ByteOffset]] internal slot.

25.3.4.1 get DataView.prototype.buffer

DataView.prototype.buffer is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[DataView]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let buffer be O.[[ViewedArrayBuffer]].
  5. Return buffer.

25.3.4.2 get DataView.prototype.byteLength

DataView.prototype.byteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[DataView]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let viewRecord be MakeDataViewWithBufferWitnessRecord(O, seq-cst).
  5. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
  6. Let size be GetViewByteLength(viewRecord).
  7. Return 𝔽(size).

25.3.4.3 get DataView.prototype.byteOffset

DataView.prototype.byteOffset is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[DataView]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let viewRecord be MakeDataViewWithBufferWitnessRecord(O, seq-cst).
  5. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
  6. Let offset be O.[[ByteOffset]].
  7. Return 𝔽(offset).

25.3.4.4 DataView.prototype.constructor

The initial value of DataView.prototype.constructor is %DataView%.

25.3.4.5 DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. Return ? GetViewValue(v, byteOffset, littleEndian, bigint64).

25.3.4.6 DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. Return ? GetViewValue(v, byteOffset, littleEndian, biguint64).

25.3.4.7 DataView.prototype.getFloat32 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, float32).

25.3.4.8 DataView.prototype.getFloat64 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, float64).

25.3.4.9 DataView.prototype.getInt8 ( byteOffset )

This method performs the following steps when called:

  1. Let v be the this value.
  2. Return ? GetViewValue(v, byteOffset, true, int8).

25.3.4.10 DataView.prototype.getInt16 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, int16).

25.3.4.11 DataView.prototype.getInt32 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, int32).

25.3.4.12 DataView.prototype.getUint8 ( byteOffset )

This method performs the following steps when called:

  1. Let v be the this value.
  2. Return ? GetViewValue(v, byteOffset, true, uint8).

25.3.4.13 DataView.prototype.getUint16 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, uint16).

25.3.4.14 DataView.prototype.getUint32 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, uint32).

25.3.4.15 DataView.prototype.setBigInt64 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. Return ? SetViewValue(v, byteOffset, littleEndian, bigint64, value).

25.3.4.16 DataView.prototype.setBigUint64 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. Return ? SetViewValue(v, byteOffset, littleEndian, biguint64, value).

25.3.4.17 DataView.prototype.setFloat32 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, float32, value).

25.3.4.18 DataView.prototype.setFloat64 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, float64, value).

25.3.4.19 DataView.prototype.setInt8 ( byteOffset, value )

This method performs the following steps when called:

  1. Let v be the this value.
  2. Return ? SetViewValue(v, byteOffset, true, int8, value).

25.3.4.20 DataView.prototype.setInt16 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, int16, value).

25.3.4.21 DataView.prototype.setInt32 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, int32, value).

25.3.4.22 DataView.prototype.setUint8 ( byteOffset, value )

This method performs the following steps when called:

  1. Let v be the this value.
  2. Return ? SetViewValue(v, byteOffset, true, uint8, value).

25.3.4.23 DataView.prototype.setUint16 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, uint16, value).

25.3.4.24 DataView.prototype.setUint32 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let v be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, uint32, value).

25.3.4.25 DataView.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "DataView".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.3.5 Properties of DataView Instances

DataView instances are ordinary objects that inherit properties from the DataView prototype object. DataView instances each have [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], and [[ByteOffset]] internal slots.

Note

The value of the [[DataView]] internal slot is not used within this specification. The simple presence of that internal slot is used within the specification to identify objects created using the DataView constructor.

25.4 The Atomics Object

The Atomics object:

  • is %Atomics%.
  • is the initial value of the "Atomics" property of the global object.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • does not have a [[Call]] internal method; it cannot be invoked as a function.

The Atomics object provides functions that operate indivisibly (atomically) on shared memory array cells as well as functions that let agents wait for and dispatch primitive events. When used with discipline, the Atomics functions allow multi-agent programs that communicate through shared memory to execute in a well-understood order even on parallel CPUs. The rules that govern shared-memory communication are provided by the memory model, defined below.

Note

For informative guidelines for programming and implementing shared memory in ECMAScript, please see the notes at the end of the memory model section.

25.4.1 Waiter Record

A Waiter Record is a Record value used to denote a particular call to Atomics.wait or Atomics.waitAsync.

A Waiter Record has fields listed in Table 73.

Table 73: Waiter Record Fields
Field Name Value Meaning
[[AgentSignifier]] an agent signifier The agent that called Atomics.wait or Atomics.waitAsync.
[[PromiseCapability]] a PromiseCapability Record or blocking If denoting a call to Atomics.waitAsync, the resulting promise, otherwise blocking.
[[TimeoutTime]] a non-negative extended mathematical value The earliest time by which timeout may be triggered; computed using time values.
[[Result]] "ok" or "timed-out" The return value of the call.

25.4.2 WaiterList Records

A WaiterList Record is used to explain waiting and notification of agents via Atomics.wait, Atomics.waitAsync, and Atomics.notify.

A WaiterList Record has fields listed in Table 74.

Table 74: WaiterList Record Fields
Field Name Value Meaning
[[Waiters]] a List of Waiter Records The calls to Atomics.wait or Atomics.waitAsync that are waiting on the location with which this WaiterList is associated.
[[MostRecentLeaveEvent]] a Synchronize event or empty The event of the most recent leaving of its critical section, or empty if its critical section has never been entered.

There can be multiple Waiter Records in a WaiterList with the same agent signifier.

The agent cluster has a store of WaiterList Records; the store is indexed by (block, i), where block is a Shared Data Block and i a byte offset into the memory of block. WaiterList Records are agent-independent: a lookup in the store of WaiterList Records by (block, i) will result in the same WaiterList Record in any agent in the agent cluster.

Each WaiterList Record has a critical section that controls exclusive access to that WaiterList Record during evaluation. Only a single agent may enter a WaiterList Record's critical section at one time. Entering and leaving a WaiterList Record's critical section is controlled by the abstract operations EnterCriticalSection and LeaveCriticalSection. Operations on a WaiterList Record—adding and removing waiting agents, traversing the list of agents, suspending and notifying agents on the list, setting and retrieving the Synchronize event—may only be performed by agents that have entered the WaiterList Record's critical section.

25.4.3 Abstract Operations for Atomics

25.4.3.1 ValidateIntegerTypedArray ( typedArray, waitable )

The abstract operation ValidateIntegerTypedArray takes arguments typedArray (an ECMAScript language value) and waitable (a Boolean) and returns either a normal completion containing a TypedArray With Buffer Witness Record, or a throw completion. It performs the following steps when called:

  1. Let taRecord be ? ValidateTypedArray(typedArray, unordered).
  2. NOTE: Bounds checking is not a synchronizing operation when typedArray's backing buffer is a growable SharedArrayBuffer.
  3. If waitable is true, then
    1. If typedArray.[[TypedArrayName]] is neither "Int32Array" nor "BigInt64Array", throw a TypeError exception.
  4. Else,
    1. Let type be TypedArrayElementType(typedArray).
    2. If IsUnclampedIntegerElementType(type) is false and IsBigIntElementType(type) is false, throw a TypeError exception.
  5. Return taRecord.

25.4.3.2 ValidateAtomicAccess ( taRecord, requestIndex )

The abstract operation ValidateAtomicAccess takes arguments taRecord (a TypedArray With Buffer Witness Record) and requestIndex (an ECMAScript language value) and returns either a normal completion containing an integer or a throw completion. It performs the following steps when called:

  1. Let length be TypedArrayLength(taRecord).
  2. Let accessIndex be ? ToIndex(requestIndex).
  3. Assert: accessIndex ≥ 0.
  4. If accessIndexlength, throw a RangeError exception.
  5. Let typedArray be taRecord.[[Object]].
  6. Let elementSize be TypedArrayElementSize(typedArray).
  7. Let offset be typedArray.[[ByteOffset]].
  8. Return (accessIndex × elementSize) + offset.

25.4.3.3 ValidateAtomicAccessOnIntegerTypedArray ( typedArray, requestIndex [ , waitable ] )

The abstract operation ValidateAtomicAccessOnIntegerTypedArray takes arguments typedArray (an ECMAScript language value) and requestIndex (an ECMAScript language value) and optional argument waitable (a Boolean) and returns either a normal completion containing an integer or a throw completion. It performs the following steps when called:

  1. If waitable is not present, set waitable to false.
  2. Let taRecord be ? ValidateIntegerTypedArray(typedArray, waitable).
  3. Return ? ValidateAtomicAccess(taRecord, requestIndex).

25.4.3.4 RevalidateAtomicAccess ( typedArray, byteIndexInBuffer )

The abstract operation RevalidateAtomicAccess takes arguments typedArray (a TypedArray) and byteIndexInBuffer (an integer) and returns either a normal completion containing unused or a throw completion. This operation revalidates the index within the backing buffer for atomic operations after all argument coercions are performed in Atomics methods, as argument coercions can have arbitrary side effects, which could cause the buffer to become out of bounds. This operation does not throw when typedArray's backing buffer is a SharedArrayBuffer. It performs the following steps when called:

  1. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(typedArray, unordered).
  2. NOTE: Bounds checking is not a synchronizing operation when typedArray's backing buffer is a growable SharedArrayBuffer.
  3. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
  4. Assert: byteIndexInBuffertypedArray.[[ByteOffset]].
  5. If byteIndexInBuffertaRecord.[[CachedBufferByteLength]], throw a RangeError exception.
  6. Return unused.

25.4.3.5 GetWaiterList ( block, i )

The abstract operation GetWaiterList takes arguments block (a Shared Data Block) and i (a non-negative integer that is evenly divisible by 4) and returns a WaiterList Record. It performs the following steps when called:

  1. Assert: i and i + 3 are valid byte offsets within the memory of block.
  2. Return the WaiterList Record that is referenced by the pair (block, i).

25.4.3.6 EnterCriticalSection ( WL )

The abstract operation EnterCriticalSection takes argument WL (a WaiterList Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is not in the critical section for any WaiterList Record.
  2. Wait until no agent is in the critical section for WL, then enter the critical section for WL (without allowing any other agent to enter).
  3. If WL.[[MostRecentLeaveEvent]] is not empty, then
    1. NOTE: A WL whose critical section has been entered at least once has a Synchronize event set by LeaveCriticalSection.
    2. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
    3. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
    4. Let enterEvent be a new Synchronize event.
    5. Append enterEvent to eventsRecord.[[EventList]].
    6. Append (WL.[[MostRecentLeaveEvent]], enterEvent) to eventsRecord.[[AgentSynchronizesWith]].
  4. Return unused.

EnterCriticalSection has contention when an agent attempting to enter the critical section must wait for another agent to leave it. When there is no contention, FIFO order of EnterCriticalSection calls is observable. When there is contention, an implementation may choose an arbitrary order but may not cause an agent to wait indefinitely.

25.4.3.7 LeaveCriticalSection ( WL )

The abstract operation LeaveCriticalSection takes argument WL (a WaiterList Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
  3. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
  4. Let leaveEvent be a new Synchronize event.
  5. Append leaveEvent to eventsRecord.[[EventList]].
  6. Set WL.[[MostRecentLeaveEvent]] to leaveEvent.
  7. Leave the critical section for WL.
  8. Return unused.

25.4.3.8 AddWaiter ( WL, waiterRecord )

The abstract operation AddWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. Assert: There is no Waiter Record in WL.[[Waiters]] whose [[PromiseCapability]] field is waiterRecord.[[PromiseCapability]] and whose [[AgentSignifier]] field is waiterRecord.[[AgentSignifier]].
  3. Append waiterRecord to WL.[[Waiters]].
  4. Return unused.

25.4.3.9 RemoveWaiter ( WL, waiterRecord )

The abstract operation RemoveWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. Assert: WL.[[Waiters]] contains waiterRecord.
  3. Remove waiterRecord from WL.[[Waiters]].
  4. Return unused.

25.4.3.10 RemoveWaiters ( WL, c )

The abstract operation RemoveWaiters takes arguments WL (a WaiterList Record) and c (a non-negative integer or +∞) and returns a List of Waiter Records. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. Let len be the number of elements in WL.[[Waiters]].
  3. Let n be min(c, len).
  4. Let L be a List whose elements are the first n elements of WL.[[Waiters]].
  5. Remove the first n elements of WL.[[Waiters]].
  6. Return L.

25.4.3.11 SuspendThisAgent ( WL, waiterRecord )

The abstract operation SuspendThisAgent takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. Assert: WL.[[Waiters]] contains waiterRecord.
  3. Let thisAgent be AgentSignifier().
  4. Assert: waiterRecord.[[AgentSignifier]] is thisAgent.
  5. Assert: waiterRecord.[[PromiseCapability]] is blocking.
  6. Assert: AgentCanSuspend() is true.
  7. Perform LeaveCriticalSection(WL) and suspend the surrounding agent until the time is waiterRecord.[[TimeoutTime]], performing the combined operation in such a way that a notification that arrives after the critical section is exited but before the suspension takes effect is not lost. The surrounding agent can only wake from suspension due to a timeout or due to another agent calling NotifyWaiter with arguments WL and thisAgent (i.e. via a call to Atomics.notify).
  8. Perform EnterCriticalSection(WL).
  9. Return unused.

25.4.3.12 NotifyWaiter ( WL, waiterRecord )

The abstract operation NotifyWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. If waiterRecord.[[PromiseCapability]] is blocking, then
    1. Wake the agent whose signifier is waiterRecord.[[AgentSignifier]] from suspension.
    2. NOTE: This causes the agent to resume execution in SuspendThisAgent.
  3. Else if AgentSignifier() is waiterRecord.[[AgentSignifier]], then
    1. Let promiseCapability be waiterRecord.[[PromiseCapability]].
    2. Perform ! Call(promiseCapability.[[Resolve]], undefined, « waiterRecord.[[Result]] »).
  4. Else,
    1. Perform EnqueueResolveInAgentJob(waiterRecord.[[AgentSignifier]], waiterRecord.[[PromiseCapability]], waiterRecord.[[Result]]).
  5. Return unused.
Note

An agent must not access another agent's promise capability in any capacity beyond passing it to the host.

25.4.3.13 EnqueueResolveInAgentJob ( agentSignifier, promiseCapability, resolution )

The abstract operation EnqueueResolveInAgentJob takes arguments agentSignifier (an agent signifier), promiseCapability (a PromiseCapability Record), and resolution (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. Let resolveJob be a new Job Abstract Closure with no parameters that captures agentSignifier, promiseCapability, and resolution and performs the following steps when called:
    1. Assert: AgentSignifier() is agentSignifier.
    2. Perform ! Call(promiseCapability.[[Resolve]], undefined, « resolution »).
    3. Return unused.
  2. Let realmInTargetAgent be ! GetFunctionRealm(promiseCapability.[[Resolve]]).
  3. Assert: agentSignifier is realmInTargetAgent.[[AgentSignifier]].
  4. Perform HostEnqueueGenericJob(resolveJob, realmInTargetAgent).
  5. Return unused.

25.4.3.14 DoWait ( mode, typedArray, index, value, timeout )

The abstract operation DoWait takes arguments mode (sync or async), typedArray (an ECMAScript language value), index (an ECMAScript language value), value (an ECMAScript language value), and timeout (an ECMAScript language value) and returns either a normal completion containing either an Object, "not-equal", "timed-out", or "ok", or a throw completion. It performs the following steps when called:

  1. Let taRecord be ? ValidateIntegerTypedArray(typedArray, true).
  2. Let buffer be taRecord.[[Object]].[[ViewedArrayBuffer]].
  3. If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception.
  4. Let i be ? ValidateAtomicAccess(taRecord, index).
  5. Let arrayTypeName be typedArray.[[TypedArrayName]].
  6. If arrayTypeName is "BigInt64Array", let v be ? ToBigInt64(value).
  7. Else, let v be ? ToInt32(value).
  8. Let q be ? ToNumber(timeout).
  9. If q is either NaN or +∞𝔽, let t be +∞; else if q is -∞𝔽, let t be 0; else let t be max((q), 0).
  10. If mode is sync and AgentCanSuspend() is false, throw a TypeError exception.
  11. Let block be buffer.[[ArrayBufferData]].
  12. Let offset be typedArray.[[ByteOffset]].
  13. Let byteIndexInBuffer be (i × 4) + offset.
  14. Let WL be GetWaiterList(block, byteIndexInBuffer).
  15. If mode is sync, then
    1. Let promiseCapability be blocking.
    2. Let resultObject be undefined.
  16. Else,
    1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
    2. Let resultObject be OrdinaryObjectCreate(%Object.prototype%).
  17. Perform EnterCriticalSection(WL).
  18. Let elementType be TypedArrayElementType(typedArray).
  19. Let w be GetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst).
  20. If vw, then
    1. Perform LeaveCriticalSection(WL).
    2. If mode is sync, return "not-equal".
    3. Perform ! CreateDataPropertyOrThrow(resultObject, "async", false).
    4. Perform ! CreateDataPropertyOrThrow(resultObject, "value", "not-equal").
    5. Return resultObject.
  21. If t is 0 and mode is async, then
    1. NOTE: There is no special handling of synchronous immediate timeouts. Asynchronous immediate timeouts have special handling in order to fail fast and avoid unnecessary Promise jobs.
    2. Perform LeaveCriticalSection(WL).
    3. Perform ! CreateDataPropertyOrThrow(resultObject, "async", false).
    4. Perform ! CreateDataPropertyOrThrow(resultObject, "value", "timed-out").
    5. Return resultObject.
  22. Let thisAgent be AgentSignifier().
  23. Let now be the time value (UTC) identifying the current time.
  24. Let additionalTimeout be an implementation-defined non-negative mathematical value.
  25. Let timeoutTime be (now) + t + additionalTimeout.
  26. NOTE: When t is +∞, timeoutTime is also +∞.
  27. Let waiterRecord be a new Waiter Record { [[AgentSignifier]]: thisAgent, [[PromiseCapability]]: promiseCapability, [[TimeoutTime]]: timeoutTime, [[Result]]: "ok" }.
  28. Perform AddWaiter(WL, waiterRecord).
  29. If mode is sync, then
    1. Perform SuspendThisAgent(WL, waiterRecord).
  30. Else if timeoutTime is finite, then
    1. Perform EnqueueAtomicsWaitAsyncTimeoutJob(WL, waiterRecord).
  31. Perform LeaveCriticalSection(WL).
  32. If mode is sync, return waiterRecord.[[Result]].
  33. Perform ! CreateDataPropertyOrThrow(resultObject, "async", true).
  34. Perform ! CreateDataPropertyOrThrow(resultObject, "value", promiseCapability.[[Promise]]).
  35. Return resultObject.
Note

additionalTimeout allows implementations to pad timeouts as necessary, such as for reducing power consumption or coarsening timer resolution to mitigate timing attacks. This value may differ from call to call of DoWait.

25.4.3.15 EnqueueAtomicsWaitAsyncTimeoutJob ( WL, waiterRecord )

The abstract operation EnqueueAtomicsWaitAsyncTimeoutJob takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. Let timeoutJob be a new Job Abstract Closure with no parameters that captures WL and waiterRecord and performs the following steps when called:
    1. Perform EnterCriticalSection(WL).
    2. If WL.[[Waiters]] contains waiterRecord, then
      1. Let timeOfJobExecution be the time value (UTC) identifying the current time.
      2. Assert: (timeOfJobExecution) ≥ waiterRecord.[[TimeoutTime]] (ignoring potential non-monotonicity of time values).
      3. Set waiterRecord.[[Result]] to "timed-out".
      4. Perform RemoveWaiter(WL, waiterRecord).
      5. Perform NotifyWaiter(WL, waiterRecord).
    3. Perform LeaveCriticalSection(WL).
    4. Return unused.
  2. Let now be the time value (UTC) identifying the current time.
  3. Let currentRealm be the current Realm Record.
  4. Perform HostEnqueueTimeoutJob(timeoutJob, currentRealm, 𝔽(waiterRecord.[[TimeoutTime]]) - now).
  5. Return unused.

25.4.3.16 AtomicCompareExchangeInSharedBlock ( block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes )

The abstract operation AtomicCompareExchangeInSharedBlock takes arguments block (a Shared Data Block), byteIndexInBuffer (an integer), elementSize (a non-negative integer), expectedBytes (a List of byte values), and replacementBytes (a List of byte values) and returns a List of byte values. It performs the following steps when called:

  1. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
  2. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
  3. Let rawBytesRead be a List of length elementSize whose elements are nondeterministically chosen byte values.
  4. NOTE: In implementations, rawBytesRead is the result of a load-link, of a load-exclusive, or of an operand of a read-modify-write instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
  5. NOTE: The comparison of the expected value and the read value is performed outside of the read-modify-write modification function to avoid needlessly strong synchronization when the expected value is not equal to the read value.
  6. If ByteListEqual(rawBytesRead, expectedBytes) is true, then
    1. Let second be a new read-modify-write modification function with parameters (oldBytes, newBytes) that captures nothing and performs the following steps atomically when called:
      1. Return newBytes.
    2. Let event be ReadModifyWriteSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize, [[Payload]]: replacementBytes, [[ModifyOp]]: second }.
  7. Else,
    1. Let event be ReadSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize }.
  8. Append event to eventsRecord.[[EventList]].
  9. Append Chosen Value Record { [[Event]]: event, [[ChosenValue]]: rawBytesRead } to execution.[[ChosenValues]].
  10. Return rawBytesRead.

25.4.3.17 AtomicReadModifyWrite ( typedArray, index, value, op )

The abstract operation AtomicReadModifyWrite takes arguments typedArray (an ECMAScript language value), index (an ECMAScript language value), value (an ECMAScript language value), and op (a read-modify-write modification function) and returns either a normal completion containing either a Number or a BigInt, or a throw completion. op takes two List of byte values arguments and returns a List of byte values. This operation atomically loads a value, combines it with another value, and stores the result of the combination. It returns the loaded value. It performs the following steps when called:

  1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. If typedArray.[[ContentType]] is bigint, let v be ? ToBigInt(value).
  3. Otherwise, let v be 𝔽(? ToIntegerOrInfinity(value)).
  4. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
  5. Let buffer be typedArray.[[ViewedArrayBuffer]].
  6. Let elementType be TypedArrayElementType(typedArray).
  7. Return GetModifySetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, op).

25.4.3.18 ByteListBitwiseOp ( op, xBytes, yBytes )

The abstract operation ByteListBitwiseOp takes arguments op (&, ^, or |), xBytes (a List of byte values), and yBytes (a List of byte values) and returns a List of byte values. The operation atomically performs a bitwise operation on all byte values of the arguments and returns a List of byte values. It performs the following steps when called:

  1. Assert: xBytes and yBytes have the same number of elements.
  2. Let result be a new empty List.
  3. Let i be 0.
  4. For each element xByte of xBytes, do
    1. Let yByte be yBytes[i].
    2. If op is &, then
      1. Let resultByte be the result of applying the bitwise AND operation to xByte and yByte.
    3. Else if op is ^, then
      1. Let resultByte be the result of applying the bitwise exclusive OR (XOR) operation to xByte and yByte.
    4. Else,
      1. Assert: op is |.
      2. Let resultByte be the result of applying the bitwise inclusive OR operation to xByte and yByte.
    5. Set i to i + 1.
    6. Append resultByte to result.
  5. Return result.

25.4.3.19 ByteListEqual ( xBytes, yBytes )

The abstract operation ByteListEqual takes arguments xBytes (a List of byte values) and yBytes (a List of byte values) and returns a Boolean. It performs the following steps when called:

  1. If xBytes and yBytes do not have the same number of elements, return false.
  2. Let i be 0.
  3. For each element xByte of xBytes, do
    1. Let yByte be yBytes[i].
    2. If xByteyByte, return false.
    3. Set i to i + 1.
  4. Return true.

25.4.4 Atomics.add ( typedArray, index, value )

This function performs the following steps when called:

  1. Let type be TypedArrayElementType(typedArray).
  2. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  3. Let add be a new read-modify-write modification function with parameters (xBytes, yBytes) that captures type and isLittleEndian and performs the following steps atomically when called:
    1. Let x be RawBytesToNumeric(type, xBytes, isLittleEndian).
    2. Let y be RawBytesToNumeric(type, yBytes, isLittleEndian).
    3. If x is a Number, then
      1. Let sum be Number::add(x, y).
    4. Else,
      1. Assert: x is a BigInt.
      2. Let sum be BigInt::add(x, y).
    5. Let sumBytes be NumericToRawBytes(type, sum, isLittleEndian).
    6. Assert: sumBytes, xBytes, and yBytes have the same number of elements.
    7. Return sumBytes.
  4. Return ? AtomicReadModifyWrite(typedArray, index, value, add).

25.4.5 Atomics.and ( typedArray, index, value )

This function performs the following steps when called:

  1. Let and be a new read-modify-write modification function with parameters (xBytes, yBytes) that captures nothing and performs the following steps atomically when called:
    1. Return ByteListBitwiseOp(&, xBytes, yBytes).
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, and).

25.4.6 Atomics.compareExchange ( typedArray, index, expectedValue, replacementValue )

This function performs the following steps when called:

  1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. Let buffer be typedArray.[[ViewedArrayBuffer]].
  3. Let block be buffer.[[ArrayBufferData]].
  4. If typedArray.[[ContentType]] is bigint, then
    1. Let expected be ? ToBigInt(expectedValue).
    2. Let replacement be ? ToBigInt(replacementValue).
  5. Else,
    1. Let expected be 𝔽(? ToIntegerOrInfinity(expectedValue)).
    2. Let replacement be 𝔽(? ToIntegerOrInfinity(replacementValue)).
  6. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
  7. Let elementType be TypedArrayElementType(typedArray).
  8. Let elementSize be TypedArrayElementSize(typedArray).
  9. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  10. Let expectedBytes be NumericToRawBytes(elementType, expected, isLittleEndian).
  11. Let replacementBytes be NumericToRawBytes(elementType, replacement, isLittleEndian).
  12. If IsSharedArrayBuffer(buffer) is true, then
    1. Let rawBytesRead be AtomicCompareExchangeInSharedBlock(block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes).
  13. Else,
    1. Let rawBytesRead be a List of length elementSize whose elements are the sequence of elementSize bytes starting with block[byteIndexInBuffer].
    2. If ByteListEqual(rawBytesRead, expectedBytes) is true, then
      1. Store the individual bytes of replacementBytes into block, starting at block[byteIndexInBuffer].
  14. Return RawBytesToNumeric(elementType, rawBytesRead, isLittleEndian).

25.4.7 Atomics.exchange ( typedArray, index, value )

This function performs the following steps when called:

  1. Let second be a new read-modify-write modification function with parameters (oldBytes, newBytes) that captures nothing and performs the following steps atomically when called:
    1. Return newBytes.
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, second).

25.4.8 Atomics.isLockFree ( size )

This function performs the following steps when called:

  1. Let n be ? ToIntegerOrInfinity(size).
  2. Let AR be the Agent Record of the surrounding agent.
  3. If n = 1, return AR.[[IsLockFree1]].
  4. If n = 2, return AR.[[IsLockFree2]].
  5. If n = 4, return true.
  6. If n = 8, return AR.[[IsLockFree8]].
  7. Return false.
Note

This function is an optimization primitive. The intuition is that if the atomic step of an atomic primitive (compareExchange, load, store, add, sub, and, or, xor, or exchange) on a datum of size n bytes will be performed without the surrounding agent acquiring a lock outside the n bytes comprising the datum, then Atomics.isLockFree(n) will return true. High-performance algorithms will use this function to determine whether to use locks or atomic operations in critical sections. If an atomic primitive is not lock-free then it is often more efficient for an algorithm to provide its own locking.

Atomics.isLockFree(4) always returns true as that can be supported on all known relevant hardware. Being able to assume this will generally simplify programs.

Regardless of the value returned by this function, all atomic operations are guaranteed to be atomic. For example, they will never have a visible operation take place in the middle of the operation (e.g., "tearing").

25.4.9 Atomics.load ( typedArray, index )

This function performs the following steps when called:

  1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
  3. Let buffer be typedArray.[[ViewedArrayBuffer]].
  4. Let elementType be TypedArrayElementType(typedArray).
  5. Return GetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst).

25.4.10 Atomics.or ( typedArray, index, value )

This function performs the following steps when called:

  1. Let or be a new read-modify-write modification function with parameters (xBytes, yBytes) that captures nothing and performs the following steps atomically when called:
    1. Return ByteListBitwiseOp(|, xBytes, yBytes).
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, or).

25.4.11 Atomics.store ( typedArray, index, value )

This function performs the following steps when called:

  1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. If typedArray.[[ContentType]] is bigint, let v be ? ToBigInt(value).
  3. Otherwise, let v be 𝔽(? ToIntegerOrInfinity(value)).
  4. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
  5. Let buffer be typedArray.[[ViewedArrayBuffer]].
  6. Let elementType be TypedArrayElementType(typedArray).
  7. Perform SetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, true, seq-cst).
  8. Return v.

25.4.12 Atomics.sub ( typedArray, index, value )

This function performs the following steps when called:

  1. Let type be TypedArrayElementType(typedArray).
  2. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  3. Let subtract be a new read-modify-write modification function with parameters (xBytes, yBytes) that captures type and isLittleEndian and performs the following steps atomically when called:
    1. Let x be RawBytesToNumeric(type, xBytes, isLittleEndian).
    2. Let y be RawBytesToNumeric(type, yBytes, isLittleEndian).
    3. If x is a Number, then
      1. Let difference be Number::subtract(x, y).
    4. Else,
      1. Assert: x is a BigInt.
      2. Let difference be BigInt::subtract(x, y).
    5. Let differenceBytes be NumericToRawBytes(type, difference, isLittleEndian).
    6. Assert: differenceBytes, xBytes, and yBytes have the same number of elements.
    7. Return differenceBytes.
  4. Return ? AtomicReadModifyWrite(typedArray, index, value, subtract).

25.4.13 Atomics.wait ( typedArray, index, value, timeout )

This function puts the surrounding agent in a wait queue and suspends it until notified or until the wait times out, returning a String differentiating those cases.

It performs the following steps when called:

  1. Return ? DoWait(sync, typedArray, index, value, timeout).

25.4.14 Atomics.waitAsync ( typedArray, index, value, timeout )

This function returns a Promise that is resolved when the calling agent is notified or the the timeout is reached.

It performs the following steps when called:

  1. Return ? DoWait(async, typedArray, index, value, timeout).

25.4.15 Atomics.notify ( typedArray, index, count )

This function notifies some agents that are sleeping in the wait queue.

It performs the following steps when called:

  1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index, true).
  2. If count is undefined, then
    1. Let c be +∞.
  3. Else,
    1. Let intCount be ? ToIntegerOrInfinity(count).
    2. Let c be max(intCount, 0).
  4. Let buffer be typedArray.[[ViewedArrayBuffer]].
  5. Let block be buffer.[[ArrayBufferData]].
  6. If IsSharedArrayBuffer(buffer) is false, return +0𝔽.
  7. Let WL be GetWaiterList(block, byteIndexInBuffer).
  8. Perform EnterCriticalSection(WL).
  9. Let S be RemoveWaiters(WL, c).
  10. For each element W of S, do
    1. Perform NotifyWaiter(WL, W).
  11. Perform LeaveCriticalSection(WL).
  12. Let n be the number of elements in S.
  13. Return 𝔽(n).

25.4.16 Atomics.xor ( typedArray, index, value )

This function performs the following steps when called:

  1. Let xor be a new read-modify-write modification function with parameters (xBytes, yBytes) that captures nothing and performs the following steps atomically when called:
    1. Return ByteListBitwiseOp(^, xBytes, yBytes).
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, xor).

25.4.17 Atomics [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Atomics".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.5 The JSON Object

The JSON object:

  • is %JSON%.
  • is the initial value of the "JSON" property of the global object.
  • is an ordinary object.
  • contains two functions, parse and stringify, that are used to parse and construct JSON texts.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • does not have a [[Call]] internal method; it cannot be invoked as a function.

The JSON Data Interchange Format is defined in ECMA-404. The JSON interchange format used in this specification is exactly that described by ECMA-404. Conforming implementations of JSON.parse and JSON.stringify must support the exact interchange format described in the ECMA-404 specification without any deletions or extensions to the format.

25.5.1 JSON.parse ( text [ , reviver ] )

This function parses a JSON text (a JSON-formatted String) and produces an ECMAScript language value. The JSON format represents literals, arrays, and objects with a syntax similar to the syntax for ECMAScript literals, Array Initializers, and Object Initializers. After parsing, JSON objects are realized as ECMAScript objects. JSON arrays are realized as ECMAScript Array instances. JSON strings, numbers, booleans, and null are realized as ECMAScript Strings, Numbers, Booleans, and null.

The optional reviver parameter is a function that takes two parameters, key and value. It can filter and transform the results. It is called with each of the key/value pairs produced by the parse, and its return value is used instead of the original value. If it returns what it received, the structure is not modified. If it returns undefined then the property is deleted from the result.

  1. Let jsonString be ? ToString(text).
  2. Parse StringToCodePoints(jsonString) as a JSON text as specified in ECMA-404. Throw a SyntaxError exception if it is not a valid JSON text as defined in that specification.
  3. Let scriptString be the string-concatenation of "(", jsonString, and ");".
  4. Let script be ParseText(StringToCodePoints(scriptString), Script).
  5. NOTE: The early error rules defined in 13.2.5.1 have special handling for the above invocation of ParseText.
  6. Assert: script is a Parse Node.
  7. Let completion be Completion(Evaluation of script).
  8. NOTE: The PropertyDefinitionEvaluation semantics defined in 13.2.5.5 have special handling for the above evaluation.
  9. Let unfiltered be completion.[[Value]].
  10. Assert: unfiltered is either a String, a Number, a Boolean, an Object that is defined by either an ArrayLiteral or an ObjectLiteral, or null.
  11. If IsCallable(reviver) is true, then
    1. Let root be OrdinaryObjectCreate(%Object.prototype%).
    2. Let rootName be the empty String.
    3. Perform ! CreateDataPropertyOrThrow(root, rootName, unfiltered).
    4. Return ? InternalizeJSONProperty(root, rootName, reviver).
  12. Else,
    1. Return unfiltered.

The "length" property of this function is 2𝔽.

Note

Valid JSON text is a subset of the ECMAScript PrimaryExpression syntax. Step 2 verifies that jsonString conforms to that subset, and step 10 asserts that that parsing and evaluation returns a value of an appropriate type.

However, because 13.2.5.5 behaves differently during JSON.parse, the same source text can produce different results when evaluated as a PrimaryExpression rather than as JSON. Furthermore, the Early Error for duplicate "__proto__" properties in object literals, which likewise does not apply during JSON.parse, means that not all texts accepted by JSON.parse are valid as a PrimaryExpression, despite matching the grammar.

25.5.1.1 InternalizeJSONProperty ( holder, name, reviver )

The abstract operation InternalizeJSONProperty takes arguments holder (an Object), name (a String), and reviver (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion.

Note 1

This algorithm intentionally does not throw an exception if either [[Delete]] or CreateDataProperty return false.

It performs the following steps when called:

  1. Let val be ? Get(holder, name).
  2. If val is an Object, then
    1. Let isArray be ? IsArray(val).
    2. If isArray is true, then
      1. Let len be ? LengthOfArrayLike(val).
      2. Let I be 0.
      3. Repeat, while I < len,
        1. Let prop be ! ToString(𝔽(I)).
        2. Let newElement be ? InternalizeJSONProperty(val, prop, reviver).
        3. If newElement is undefined, then
          1. Perform ? val.[[Delete]](prop).
        4. Else,
          1. Perform ? CreateDataProperty(val, prop, newElement).
        5. Set I to I + 1.
    3. Else,
      1. Let keys be ? EnumerableOwnProperties(val, key).
      2. For each String P of keys, do
        1. Let newElement be ? InternalizeJSONProperty(val, P, reviver).
        2. If newElement is undefined, then
          1. Perform ? val.[[Delete]](P).
        3. Else,
          1. Perform ? CreateDataProperty(val, P, newElement).
  3. Return ? Call(reviver, holder, « name, val »).

It is not permitted for a conforming implementation of JSON.parse to extend the JSON grammars. If an implementation wishes to support a modified or extended JSON interchange format it must do so by defining a different parse function.

Note 2

In the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten.

25.5.2 JSON.stringify ( value [ , replacer [ , space ] ] )

This function returns a String in UTF-16 encoded JSON format representing an ECMAScript language value, or undefined. It can take three parameters. The value parameter is an ECMAScript language value, which is usually an object or array, although it can also be a String, Boolean, Number or null. The optional replacer parameter is either a function that alters the way objects and arrays are stringified, or an array of Strings and Numbers that acts as an inclusion list for selecting the object properties that will be stringified. The optional space parameter is a String or Number that allows the result to have white space injected into it to improve human readability.

It performs the following steps when called:

  1. Let stack be a new empty List.
  2. Let indent be the empty String.
  3. Let PropertyList be undefined.
  4. Let ReplacerFunction be undefined.
  5. If replacer is an Object, then
    1. If IsCallable(replacer) is true, then
      1. Set ReplacerFunction to replacer.
    2. Else,
      1. Let isArray be ? IsArray(replacer).
      2. If isArray is true, then
        1. Set PropertyList to a new empty List.
        2. Let len be ? LengthOfArrayLike(replacer).
        3. Let k be 0.
        4. Repeat, while k < len,
          1. Let prop be ! ToString(𝔽(k)).
          2. Let v be ? Get(replacer, prop).
          3. Let item be undefined.
          4. If v is a String, then
            1. Set item to v.
          5. Else if v is a Number, then
            1. Set item to ! ToString(v).
          6. Else if v is an Object, then
            1. If v has a [[StringData]] or [[NumberData]] internal slot, set item to ? ToString(v).
          7. If item is not undefined and PropertyList does not contain item, then
            1. Append item to PropertyList.
          8. Set k to k + 1.
  6. If space is an Object, then
    1. If space has a [[NumberData]] internal slot, then
      1. Set space to ? ToNumber(space).
    2. Else if space has a [[StringData]] internal slot, then
      1. Set space to ? ToString(space).
  7. If space is a Number, then
    1. Let spaceMV be ! ToIntegerOrInfinity(space).
    2. Set spaceMV to min(10, spaceMV).
    3. If spaceMV < 1, let gap be the empty String; otherwise let gap be the String value containing spaceMV occurrences of the code unit 0x0020 (SPACE).
  8. Else if space is a String, then
    1. If the length of space ≤ 10, let gap be space; otherwise let gap be the substring of space from 0 to 10.
  9. Else,
    1. Let gap be the empty String.
  10. Let wrapper be OrdinaryObjectCreate(%Object.prototype%).
  11. Perform ! CreateDataPropertyOrThrow(wrapper, the empty String, value).
  12. Let state be the JSON Serialization Record { [[ReplacerFunction]]: ReplacerFunction, [[Stack]]: stack, [[Indent]]: indent, [[Gap]]: gap, [[PropertyList]]: PropertyList }.
  13. Return ? SerializeJSONProperty(state, the empty String, wrapper).

The "length" property of this function is 3𝔽.

Note 1

JSON structures are allowed to be nested to any depth, but they must be acyclic. If value is or contains a cyclic structure, then this function must throw a TypeError exception. This is an example of a value that cannot be stringified:

a = [];
a[0] = a;
my_text = JSON.stringify(a); // This must throw a TypeError.
Note 2

Symbolic primitive values are rendered as follows:

  • The null value is rendered in JSON text as the String value "null".
  • The undefined value is not rendered.
  • The true value is rendered in JSON text as the String value "true".
  • The false value is rendered in JSON text as the String value "false".
Note 3

String values are wrapped in QUOTATION MARK (") code units. The code units " and \ are escaped with \ prefixes. Control characters code units are replaced with escape sequences \uHHHH, or with the shorter forms, \b (BACKSPACE), \f (FORM FEED), \n (LINE FEED), \r (CARRIAGE RETURN), \t (CHARACTER TABULATION).

Note 4

Finite numbers are stringified as if by calling ToString(number). NaN and Infinity regardless of sign are represented as the String value "null".

Note 5

Values that do not have a JSON representation (such as undefined and functions) do not produce a String. Instead they produce the undefined value. In arrays these values are represented as the String value "null". In objects an unrepresentable value causes the property to be excluded from stringification.

Note 6

An object is rendered as U+007B (LEFT CURLY BRACKET) followed by zero or more properties, separated with a U+002C (COMMA), closed with a U+007D (RIGHT CURLY BRACKET). A property is a quoted String representing the property name, a U+003A (COLON), and then the stringified property value. An array is rendered as an opening U+005B (LEFT SQUARE BRACKET) followed by zero or more values, separated with a U+002C (COMMA), closed with a U+005D (RIGHT SQUARE BRACKET).

25.5.2.1 JSON Serialization Record

A JSON Serialization Record is a Record value used to enable serialization to the JSON format.

JSON Serialization Records have the fields listed in Table 75.

Table 75: JSON Serialization Record Fields
Field Name Value Meaning
[[ReplacerFunction]] a function object or undefined A function that can supply replacement values for object properties (from JSON.stringify's replacer parameter).
[[PropertyList]] either a List of Strings or undefined The names of properties to include when serializing a non-array object (from JSON.stringify's replacer parameter).
[[Gap]] a String The unit of indentation (from JSON.stringify's space parameter).
[[Stack]] a List of Objects The set of nested objects that are in the process of being serialized. Used to detect cyclic structures.
[[Indent]] a String The current indentation.

25.5.2.2 SerializeJSONProperty ( state, key, holder )

The abstract operation SerializeJSONProperty takes arguments state (a JSON Serialization Record), key (a String), and holder (an Object) and returns either a normal completion containing either a String or undefined, or a throw completion. It performs the following steps when called:

  1. Let value be ? Get(holder, key).
  2. If value is an Object or value is a BigInt, then
    1. Let toJSON be ? GetV(value, "toJSON").
    2. If IsCallable(toJSON) is true, then
      1. Set value to ? Call(toJSON, value, « key »).
  3. If state.[[ReplacerFunction]] is not undefined, then
    1. Set value to ? Call(state.[[ReplacerFunction]], holder, « key, value »).
  4. If value is an Object, then
    1. If value has a [[NumberData]] internal slot, then
      1. Set value to ? ToNumber(value).
    2. Else if value has a [[StringData]] internal slot, then
      1. Set value to ? ToString(value).
    3. Else if value has a [[BooleanData]] internal slot, then
      1. Set value to value.[[BooleanData]].
    4. Else if value has a [[BigIntData]] internal slot, then
      1. Set value to value.[[BigIntData]].
  5. If value is null, return "null".
  6. If value is true, return "true".
  7. If value is false, return "false".
  8. If value is a String, return QuoteJSONString(value).
  9. If value is a Number, then
    1. If value is finite, return ! ToString(value).
    2. Return "null".
  10. If value is a BigInt, throw a TypeError exception.
  11. If value is an Object and IsCallable(value) is false, then
    1. Let isArray be ? IsArray(value).
    2. If isArray is true, return ? SerializeJSONArray(state, value).
    3. Return ? SerializeJSONObject(state, value).
  12. Return undefined.

25.5.2.3 QuoteJSONString ( value )

The abstract operation QuoteJSONString takes argument value (a String) and returns a String. It wraps value in 0x0022 (QUOTATION MARK) code units and escapes certain other code units within it. This operation interprets value as a sequence of UTF-16 encoded code points, as described in 6.1.4. It performs the following steps when called:

  1. Let product be the String value consisting solely of the code unit 0x0022 (QUOTATION MARK).
  2. For each code point C of StringToCodePoints(value), do
    1. If C is listed in the “Code Point” column of Table 76, then
      1. Set product to the string-concatenation of product and the escape sequence for C as specified in the “Escape Sequence” column of the corresponding row.
    2. Else if C has a numeric value less than 0x0020 (SPACE) or C has the same numeric value as a leading surrogate or trailing surrogate, then
      1. Let unit be the code unit whose numeric value is the numeric value of C.
      2. Set product to the string-concatenation of product and UnicodeEscape(unit).
    3. Else,
      1. Set product to the string-concatenation of product and UTF16EncodeCodePoint(C).
  3. Set product to the string-concatenation of product and the code unit 0x0022 (QUOTATION MARK).
  4. Return product.
Table 76: JSON Single Character Escape Sequences
Code Point Unicode Character Name Escape Sequence
U+0008 BACKSPACE \b
U+0009 CHARACTER TABULATION \t
U+000A LINE FEED (LF) \n
U+000C FORM FEED (FF) \f
U+000D CARRIAGE RETURN (CR) \r
U+0022 QUOTATION MARK \"
U+005C REVERSE SOLIDUS \\

25.5.2.4 UnicodeEscape ( C )

The abstract operation UnicodeEscape takes argument C (a code unit) and returns a String. It represents C as a Unicode escape sequence. It performs the following steps when called:

  1. Let n be the numeric value of C.
  2. Assert: n ≤ 0xFFFF.
  3. Let hex be the String representation of n, formatted as a lowercase hexadecimal number.
  4. Return the string-concatenation of the code unit 0x005C (REVERSE SOLIDUS), "u", and StringPad(hex, 4, "0", start).

25.5.2.5 SerializeJSONObject ( state, value )

The abstract operation SerializeJSONObject takes arguments state (a JSON Serialization Record) and value (an Object) and returns either a normal completion containing a String or a throw completion. It serializes an object. It performs the following steps when called:

  1. If state.[[Stack]] contains value, throw a TypeError exception because the structure is cyclical.
  2. Append value to state.[[Stack]].
  3. Let stepback be state.[[Indent]].
  4. Set state.[[Indent]] to the string-concatenation of state.[[Indent]] and state.[[Gap]].
  5. If state.[[PropertyList]] is not undefined, then
    1. Let K be state.[[PropertyList]].
  6. Else,
    1. Let K be ? EnumerableOwnProperties(value, key).
  7. Let partial be a new empty List.
  8. For each element P of K, do
    1. Let strP be ? SerializeJSONProperty(state, P, value).
    2. If strP is not undefined, then
      1. Let member be QuoteJSONString(P).
      2. Set member to the string-concatenation of member and ":".
      3. If state.[[Gap]] is not the empty String, then
        1. Set member to the string-concatenation of member and the code unit 0x0020 (SPACE).
      4. Set member to the string-concatenation of member and strP.
      5. Append member to partial.
  9. If partial is empty, then
    1. Let final be "{}".
  10. Else,
    1. If state.[[Gap]] is the empty String, then
      1. Let properties be the String value formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with the code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String.
      2. Let final be the string-concatenation of "{", properties, and "}".
    2. Else,
      1. Let separator be the string-concatenation of the code unit 0x002C (COMMA), the code unit 0x000A (LINE FEED), and state.[[Indent]].
      2. Let properties be the String value formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with separator. The separator String is not inserted either before the first String or after the last String.
      3. Let final be the string-concatenation of "{", the code unit 0x000A (LINE FEED), state.[[Indent]], properties, the code unit 0x000A (LINE FEED), stepback, and "}".
  11. Remove the last element of state.[[Stack]].
  12. Set state.[[Indent]] to stepback.
  13. Return final.

25.5.2.6 SerializeJSONArray ( state, value )

The abstract operation SerializeJSONArray takes arguments state (a JSON Serialization Record) and value (an ECMAScript language value) and returns either a normal completion containing a String or a throw completion. It serializes an array. It performs the following steps when called:

  1. If state.[[Stack]] contains value, throw a TypeError exception because the structure is cyclical.
  2. Append value to state.[[Stack]].
  3. Let stepback be state.[[Indent]].
  4. Set state.[[Indent]] to the string-concatenation of state.[[Indent]] and state.[[Gap]].
  5. Let partial be a new empty List.
  6. Let len be ? LengthOfArrayLike(value).
  7. Let index be 0.
  8. Repeat, while index < len,
    1. Let strP be ? SerializeJSONProperty(state, ! ToString(𝔽(index)), value).
    2. If strP is undefined, then
      1. Append "null" to partial.
    3. Else,
      1. Append strP to partial.
    4. Set index to index + 1.
  9. If partial is empty, then
    1. Let final be "[]".
  10. Else,
    1. If state.[[Gap]] is the empty String, then
      1. Let properties be the String value formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with the code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String.
      2. Let final be the string-concatenation of "[", properties, and "]".
    2. Else,
      1. Let separator be the string-concatenation of the code unit 0x002C (COMMA), the code unit 0x000A (LINE FEED), and state.[[Indent]].
      2. Let properties be the String value formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with separator. The separator String is not inserted either before the first String or after the last String.
      3. Let final be the string-concatenation of "[", the code unit 0x000A (LINE FEED), state.[[Indent]], properties, the code unit 0x000A (LINE FEED), stepback, and "]".
  11. Remove the last element of state.[[Stack]].
  12. Set state.[[Indent]] to stepback.
  13. Return final.
Note

The representation of arrays includes only the elements in the interval from +0𝔽 (inclusive) to array.length (exclusive). Properties whose keys are not array indices are excluded from the stringification. An array is stringified as an opening LEFT SQUARE BRACKET, elements separated by COMMA, and a closing RIGHT SQUARE BRACKET.

25.5.3 JSON [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "JSON".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

26 Managing Memory

26.1 WeakRef Objects

A WeakRef is an object that is used to refer to a target object or symbol without preserving it from garbage collection. WeakRefs can be dereferenced to allow access to the target value, if the target hasn't been reclaimed by garbage collection.

26.1.1 The WeakRef Constructor

The WeakRef constructor:

  • is %WeakRef%.
  • is the initial value of the "WeakRef" property of the global object.
  • creates and initializes a new WeakRef when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified WeakRef behaviour must include a super call to the WeakRef constructor to create and initialize the subclass instance with the internal state necessary to support the WeakRef.prototype built-in methods.

26.1.1.1 WeakRef ( target )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If CanBeHeldWeakly(target) is false, throw a TypeError exception.
  3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRef.prototype%", « [[WeakRefTarget]] »).
  4. Perform AddToKeptObjects(target).
  5. Set weakRef.[[WeakRefTarget]] to target.
  6. Return weakRef.

26.1.2 Properties of the WeakRef Constructor

The WeakRef constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

26.1.2.1 WeakRef.prototype

The initial value of WeakRef.prototype is the WeakRef prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

26.1.3 Properties of the WeakRef Prototype Object

The WeakRef prototype object:

  • is %WeakRef.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have a [[WeakRefTarget]] internal slot.

26.1.3.1 WeakRef.prototype.constructor

The initial value of WeakRef.prototype.constructor is %WeakRef%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

26.1.3.2 WeakRef.prototype.deref ( )

This method performs the following steps when called:

  1. Let weakRef be the this value.
  2. Perform ? RequireInternalSlot(weakRef, [[WeakRefTarget]]).
  3. Return WeakRefDeref(weakRef).
Note

If the WeakRef returns a target value that is not undefined, then this target value should not be garbage collected until the current execution of ECMAScript code has completed. The AddToKeptObjects operation makes sure read consistency is maintained.

let target = { foo() {} };
let weakRef = new WeakRef(target);

// ... later ...

if (weakRef.deref()) {
  weakRef.deref().foo();
}

In the above example, if the first deref does not evaluate to undefined then the second deref cannot either.

26.1.3.3 WeakRef.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "WeakRef".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

26.1.4 WeakRef Abstract Operations

26.1.4.1 WeakRefDeref ( weakRef )

The abstract operation WeakRefDeref takes argument weakRef (a WeakRef) and returns an ECMAScript language value. It performs the following steps when called:

  1. Let target be weakRef.[[WeakRefTarget]].
  2. If target is not empty, then
    1. Perform AddToKeptObjects(target).
    2. Return target.
  3. Return undefined.
Note

This abstract operation is defined separately from WeakRef.prototype.deref strictly to make it possible to succinctly define liveness.

26.1.5 Properties of WeakRef Instances

WeakRef instances are ordinary objects that inherit properties from the WeakRef prototype. WeakRef instances also have a [[WeakRefTarget]] internal slot.

26.2 FinalizationRegistry Objects

A FinalizationRegistry is an object that manages registration and unregistration of cleanup operations that are performed when target objects and symbols are garbage collected.

26.2.1 The FinalizationRegistry Constructor

The FinalizationRegistry constructor:

  • is %FinalizationRegistry%.
  • is the initial value of the "FinalizationRegistry" property of the global object.
  • creates and initializes a new FinalizationRegistry when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified FinalizationRegistry behaviour must include a super call to the FinalizationRegistry constructor to create and initialize the subclass instance with the internal state necessary to support the FinalizationRegistry.prototype built-in methods.

26.2.1.1 FinalizationRegistry ( cleanupCallback )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If IsCallable(cleanupCallback) is false, throw a TypeError exception.
  3. Let finalizationRegistry be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationRegistry.prototype%", « [[Realm]], [[CleanupCallback]], [[Cells]] »).
  4. Let fn be the active function object.
  5. Set finalizationRegistry.[[Realm]] to fn.[[Realm]].
  6. Set finalizationRegistry.[[CleanupCallback]] to HostMakeJobCallback(cleanupCallback).
  7. Set finalizationRegistry.[[Cells]] to a new empty List.
  8. Return finalizationRegistry.

26.2.2 Properties of the FinalizationRegistry Constructor

The FinalizationRegistry constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

26.2.2.1 FinalizationRegistry.prototype

The initial value of FinalizationRegistry.prototype is the FinalizationRegistry prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

26.2.3 Properties of the FinalizationRegistry Prototype Object

The FinalizationRegistry prototype object:

  • is %FinalizationRegistry.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have [[Cells]] and [[CleanupCallback]] internal slots.

26.2.3.1 FinalizationRegistry.prototype.constructor

The initial value of FinalizationRegistry.prototype.constructor is %FinalizationRegistry%.

26.2.3.2 FinalizationRegistry.prototype.register ( target, heldValue [ , unregisterToken ] )

This method performs the following steps when called:

  1. Let finalizationRegistry be the this value.
  2. Perform ? RequireInternalSlot(finalizationRegistry, [[Cells]]).
  3. If CanBeHeldWeakly(target) is false, throw a TypeError exception.
  4. If SameValue(target, heldValue) is true, throw a TypeError exception.
  5. If CanBeHeldWeakly(unregisterToken) is false, then
    1. If unregisterToken is not undefined, throw a TypeError exception.
    2. Set unregisterToken to empty.
  6. Let cell be the Record { [[WeakRefTarget]]: target, [[HeldValue]]: heldValue, [[UnregisterToken]]: unregisterToken }.
  7. Append cell to finalizationRegistry.[[Cells]].
  8. Return undefined.
Note

Based on the algorithms and definitions in this specification, cell.[[HeldValue]] is live when finalizationRegistry.[[Cells]] contains cell; however, this does not necessarily mean that cell.[[UnregisterToken]] or cell.[[Target]] are live. For example, registering an object with itself as its unregister token would not keep the object alive forever.

26.2.3.3 FinalizationRegistry.prototype.unregister ( unregisterToken )

This method performs the following steps when called:

  1. Let finalizationRegistry be the this value.
  2. Perform ? RequireInternalSlot(finalizationRegistry, [[Cells]]).
  3. If CanBeHeldWeakly(unregisterToken) is false, throw a TypeError exception.
  4. Let removed be false.
  5. For each Record { [[WeakRefTarget]], [[HeldValue]], [[UnregisterToken]] } cell of finalizationRegistry.[[Cells]], do
    1. If cell.[[UnregisterToken]] is not empty and SameValue(cell.[[UnregisterToken]], unregisterToken) is true, then
      1. Remove cell from finalizationRegistry.[[Cells]].
      2. Set removed to true.
  6. Return removed.

26.2.3.4 FinalizationRegistry.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "FinalizationRegistry".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

26.2.4 Properties of FinalizationRegistry Instances

FinalizationRegistry instances are ordinary objects that inherit properties from the FinalizationRegistry prototype. FinalizationRegistry instances also have [[Cells]] and [[CleanupCallback]] internal slots.

27 Control Abstraction Objects

27.1 Iteration

27.1.1 Common Iteration Interfaces

An interface is a set of property keys whose associated values match a specific specification. Any object that provides all the properties as described by an interface's specification conforms to that interface. An interface is not represented by a distinct object. There may be many separately implemented objects that conform to any interface. An individual object may conform to multiple interfaces.

27.1.1.1 The Iterable Interface

The Iterable interface includes the property described in Table 77:

Table 77: Iterable Interface Required Properties
Property Value Requirements
@@iterator a function that returns an Iterator object The returned object must conform to the Iterator interface.

27.1.1.2 The Iterator Interface

An object that implements the Iterator interface must include the property in Table 78. Such objects may also implement the properties in Table 79.

Table 78: Iterator Interface Required Properties
Property Value Requirements
"next" a function that returns an IteratorResult object The returned object must conform to the IteratorResult interface. If a previous call to the next method of an Iterator has returned an IteratorResult object whose "done" property is true, then all subsequent calls to the next method of that object should also return an IteratorResult object whose "done" property is true. However, this requirement is not enforced.
Note 1

Arguments may be passed to the next function but their interpretation and validity is dependent upon the target Iterator. The for-of statement and other common users of Iterators do not pass any arguments, so Iterator objects that expect to be used in such a manner must be prepared to deal with being called with no arguments.

Table 79: Iterator Interface Optional Properties
Property Value Requirements
"return" a function that returns an IteratorResult object The returned object must conform to the IteratorResult interface. Invoking this method notifies the Iterator object that the caller does not intend to make any more next method calls to the Iterator. The returned IteratorResult object will typically have a "done" property whose value is true, and a "value" property with the value passed as the argument of the return method. However, this requirement is not enforced.
"throw" a function that returns an IteratorResult object The returned object must conform to the IteratorResult interface. Invoking this method notifies the Iterator object that the caller has detected an error condition. The argument may be used to identify the error condition and typically will be an exception object. A typical response is to throw the value passed as the argument. If the method does not throw, the returned IteratorResult object will typically have a "done" property whose value is true.
Note 2

Typically callers of these methods should check for their existence before invoking them. Certain ECMAScript language features including for-of, yield*, and array destructuring call these methods after performing an existence check. Most ECMAScript library functions that accept Iterable objects as arguments also conditionally call them.

27.1.1.3 The AsyncIterable Interface

The AsyncIterable interface includes the properties described in Table 80:

Table 80: AsyncIterable Interface Required Properties
Property Value Requirements
@@asyncIterator a function that returns an AsyncIterator object The returned object must conform to the AsyncIterator interface.

27.1.1.4 The AsyncIterator Interface

An object that implements the AsyncIterator interface must include the properties in Table 81. Such objects may also implement the properties in Table 82.

Table 81: AsyncIterator Interface Required Properties
Property Value Requirements
"next" a function that returns a promise for an IteratorResult object

The returned promise, when fulfilled, must fulfill with an object that conforms to the IteratorResult interface. If a previous call to the next method of an AsyncIterator has returned a promise for an IteratorResult object whose "done" property is true, then all subsequent calls to the next method of that object should also return a promise for an IteratorResult object whose "done" property is true. However, this requirement is not enforced.

Additionally, the IteratorResult object that serves as a fulfillment value should have a "value" property whose value is not a promise (or "thenable"). However, this requirement is also not enforced.

Note 1

Arguments may be passed to the next function but their interpretation and validity is dependent upon the target AsyncIterator. The for-await-of statement and other common users of AsyncIterators do not pass any arguments, so AsyncIterator objects that expect to be used in such a manner must be prepared to deal with being called with no arguments.

Table 82: AsyncIterator Interface Optional Properties
Property Value Requirements
"return" a function that returns a promise for an IteratorResult object

The returned promise, when fulfilled, must fulfill with an object that conforms to the IteratorResult interface. Invoking this method notifies the AsyncIterator object that the caller does not intend to make any more next method calls to the AsyncIterator. The returned promise will fulfill with an IteratorResult object which will typically have a "done" property whose value is true, and a "value" property with the value passed as the argument of the return method. However, this requirement is not enforced.

Additionally, the IteratorResult object that serves as a fulfillment value should have a "value" property whose value is not a promise (or "thenable"). If the argument value is used in the typical manner, then if it is a rejected promise, a promise rejected with the same reason should be returned; if it is a fulfilled promise, then its fulfillment value should be used as the "value" property of the returned promise's IteratorResult object fulfillment value. However, these requirements are also not enforced.

"throw" a function that returns a promise for an IteratorResult object

The returned promise, when fulfilled, must fulfill with an object that conforms to the IteratorResult interface. Invoking this method notifies the AsyncIterator object that the caller has detected an error condition. The argument may be used to identify the error condition and typically will be an exception object. A typical response is to return a rejected promise which rejects with the value passed as the argument.

If the returned promise is fulfilled, the IteratorResult fulfillment value will typically have a "done" property whose value is true. Additionally, it should have a "value" property whose value is not a promise (or "thenable"), but this requirement is not enforced.

Note 2

Typically callers of these methods should check for their existence before invoking them. Certain ECMAScript language features including for-await-of and yield* call these methods after performing an existence check.

27.1.1.5 The IteratorResult Interface

The IteratorResult interface includes the properties listed in Table 83:

Table 83: IteratorResult Interface Properties
Property Value Requirements
"done" a Boolean This is the result status of an iterator next method call. If the end of the iterator was reached "done" is true. If the end was not reached "done" is false and a value is available. If a "done" property (either own or inherited) does not exist, it is considered to have the value false.
"value" an ECMAScript language value If done is false, this is the current iteration element value. If done is true, this is the return value of the iterator, if it supplied one. If the iterator does not have a return value, "value" is undefined. In that case, the "value" property may be absent from the conforming object if it does not inherit an explicit "value" property.

27.1.2 The %IteratorPrototype% Object

The %IteratorPrototype% object:

Note

All objects defined in this specification that implement the Iterator interface also inherit from %IteratorPrototype%. ECMAScript code may also define objects that inherit from %IteratorPrototype%. The %IteratorPrototype% object provides a place where additional methods that are applicable to all iterator objects may be added.

The following expression is one way that ECMAScript code can access the %IteratorPrototype% object:

Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))

27.1.2.1 %IteratorPrototype% [ @@iterator ] ( )

This function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "[Symbol.iterator]".

27.1.3 The %AsyncIteratorPrototype% Object

The %AsyncIteratorPrototype% object:

Note

All objects defined in this specification that implement the AsyncIterator interface also inherit from %AsyncIteratorPrototype%. ECMAScript code may also define objects that inherit from %AsyncIteratorPrototype%. The %AsyncIteratorPrototype% object provides a place where additional methods that are applicable to all async iterator objects may be added.

27.1.3.1 %AsyncIteratorPrototype% [ @@asyncIterator ] ( )

This function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "[Symbol.asyncIterator]".

27.1.4 Async-from-Sync Iterator Objects

An Async-from-Sync Iterator object is an async iterator that adapts a specific synchronous iterator. There is not a named constructor for Async-from-Sync Iterator objects. Instead, Async-from-Sync iterator objects are created by the CreateAsyncFromSyncIterator abstract operation as needed.

27.1.4.1 CreateAsyncFromSyncIterator ( syncIteratorRecord )

The abstract operation CreateAsyncFromSyncIterator takes argument syncIteratorRecord (an Iterator Record) and returns an Iterator Record. It is used to create an async Iterator Record from a synchronous Iterator Record. It performs the following steps when called:

  1. Let asyncIterator be OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »).
  2. Set asyncIterator.[[SyncIteratorRecord]] to syncIteratorRecord.
  3. Let nextMethod be ! Get(asyncIterator, "next").
  4. Let iteratorRecord be the Iterator Record { [[Iterator]]: asyncIterator, [[NextMethod]]: nextMethod, [[Done]]: false }.
  5. Return iteratorRecord.

27.1.4.2 The %AsyncFromSyncIteratorPrototype% Object

The %AsyncFromSyncIteratorPrototype% object:

  • has properties that are inherited by all Async-from-Sync Iterator Objects.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %AsyncIteratorPrototype%.
  • has the following properties:

27.1.4.2.1 %AsyncFromSyncIteratorPrototype%.next ( [ value ] )

  1. Let O be the this value.
  2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
  3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  4. Let syncIteratorRecord be O.[[SyncIteratorRecord]].
  5. If value is present, then
    1. Let result be Completion(IteratorNext(syncIteratorRecord, value)).
  6. Else,
    1. Let result be Completion(IteratorNext(syncIteratorRecord)).
  7. IfAbruptRejectPromise(result, promiseCapability).
  8. Return AsyncFromSyncIteratorContinuation(result, promiseCapability).

27.1.4.2.2 %AsyncFromSyncIteratorPrototype%.return ( [ value ] )

  1. Let O be the this value.
  2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
  3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  4. Let syncIterator be O.[[SyncIteratorRecord]].[[Iterator]].
  5. Let return be Completion(GetMethod(syncIterator, "return")).
  6. IfAbruptRejectPromise(return, promiseCapability).
  7. If return is undefined, then
    1. Let iterResult be CreateIterResultObject(value, true).
    2. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iterResult »).
    3. Return promiseCapability.[[Promise]].
  8. If value is present, then
    1. Let result be Completion(Call(return, syncIterator, « value »)).
  9. Else,
    1. Let result be Completion(Call(return, syncIterator)).
  10. IfAbruptRejectPromise(result, promiseCapability).
  11. If result is not an Object, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
    2. Return promiseCapability.[[Promise]].
  12. Return AsyncFromSyncIteratorContinuation(result, promiseCapability).

27.1.4.2.3 %AsyncFromSyncIteratorPrototype%.throw ( [ value ] )

Note
In this specification, value is always provided, but is left optional for consistency with %AsyncFromSyncIteratorPrototype%.return ( [ value ] ).
  1. Let O be the this value.
  2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
  3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  4. Let syncIterator be O.[[SyncIteratorRecord]].[[Iterator]].
  5. Let throw be Completion(GetMethod(syncIterator, "throw")).
  6. IfAbruptRejectPromise(throw, promiseCapability).
  7. If throw is undefined, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « value »).
    2. Return promiseCapability.[[Promise]].
  8. If value is present, then
    1. Let result be Completion(Call(throw, syncIterator, « value »)).
  9. Else,
    1. Let result be Completion(Call(throw, syncIterator)).
  10. IfAbruptRejectPromise(result, promiseCapability).
  11. If result is not an Object, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
    2. Return promiseCapability.[[Promise]].
  12. Return AsyncFromSyncIteratorContinuation(result, promiseCapability).

27.1.4.3 Properties of Async-from-Sync Iterator Instances

Async-from-Sync Iterator instances are ordinary objects that inherit properties from the %AsyncFromSyncIteratorPrototype% intrinsic object. Async-from-Sync Iterator instances are initially created with the internal slots listed in Table 84. Async-from-Sync Iterator instances are not directly observable from ECMAScript code.

Table 84: Internal Slots of Async-from-Sync Iterator Instances
Internal Slot Type Description
[[SyncIteratorRecord]] an Iterator Record Represents the original synchronous iterator which is being adapted.

27.1.4.4 AsyncFromSyncIteratorContinuation ( result, promiseCapability )

The abstract operation AsyncFromSyncIteratorContinuation takes arguments result (an Object) and promiseCapability (a PromiseCapability Record for an intrinsic %Promise%) and returns a Promise. It performs the following steps when called:

  1. NOTE: Because promiseCapability is derived from the intrinsic %Promise%, the calls to promiseCapability.[[Reject]] entailed by the use IfAbruptRejectPromise below are guaranteed not to throw.
  2. Let done be Completion(IteratorComplete(result)).
  3. IfAbruptRejectPromise(done, promiseCapability).
  4. Let value be Completion(IteratorValue(result)).
  5. IfAbruptRejectPromise(value, promiseCapability).
  6. Let valueWrapper be Completion(PromiseResolve(%Promise%, value)).
  7. IfAbruptRejectPromise(valueWrapper, promiseCapability).
  8. Let unwrap be a new Abstract Closure with parameters (v) that captures done and performs the following steps when called:
    1. Return CreateIterResultObject(v, done).
  9. Let onFulfilled be CreateBuiltinFunction(unwrap, 1, "", « »).
  10. NOTE: onFulfilled is used when processing the "value" property of an IteratorResult object in order to wait for its value if it is a promise and re-package the result in a new "unwrapped" IteratorResult object.
  11. Perform PerformPromiseThen(valueWrapper, onFulfilled, undefined, promiseCapability).
  12. Return promiseCapability.[[Promise]].

27.2 Promise Objects

A Promise is an object that is used as a placeholder for the eventual results of a deferred (and possibly asynchronous) computation.

Any Promise is in one of three mutually exclusive states: fulfilled, rejected, and pending:

  • A promise p is fulfilled if p.then(f, r) will immediately enqueue a Job to call the function f.
  • A promise p is rejected if p.then(f, r) will immediately enqueue a Job to call the function r.
  • A promise is pending if it is neither fulfilled nor rejected.

A promise is said to be settled if it is not pending, i.e. if it is either fulfilled or rejected.

A promise is resolved if it is settled or if it has been “locked in” to match the state of another promise. Attempting to resolve or reject a resolved promise has no effect. A promise is unresolved if it is not resolved. An unresolved promise is always in the pending state. A resolved promise may be pending, fulfilled or rejected.

27.2.1 Promise Abstract Operations

27.2.1.1 PromiseCapability Records

A PromiseCapability Record is a Record value used to encapsulate a Promise or promise-like object along with the functions that are capable of resolving or rejecting that promise. PromiseCapability Records are produced by the NewPromiseCapability abstract operation.

PromiseCapability Records have the fields listed in Table 85.

Table 85: PromiseCapability Record Fields
Field Name Value Meaning
[[Promise]] an Object An object that is usable as a promise.
[[Resolve]] a function object The function that is used to resolve the given promise.
[[Reject]] a function object The function that is used to reject the given promise.

27.2.1.1.1 IfAbruptRejectPromise ( value, capability )

IfAbruptRejectPromise is a shorthand for a sequence of algorithm steps that use a PromiseCapability Record. An algorithm step of the form:

  1. IfAbruptRejectPromise(value, capability).

means the same thing as:

  1. Assert: value is a Completion Record.
  2. If value is an abrupt completion, then
    1. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »).
    2. Return capability.[[Promise]].
  3. Else,
    1. Set value to ! value.

27.2.1.2 PromiseReaction Records

A PromiseReaction Record is a Record value used to store information about how a promise should react when it becomes resolved or rejected with a given value. PromiseReaction Records are created by the PerformPromiseThen abstract operation, and are used by the Abstract Closure returned by NewPromiseReactionJob.

PromiseReaction Records have the fields listed in Table 86.

Table 86: PromiseReaction Record Fields
Field Name Value Meaning
[[Capability]] a PromiseCapability Record or undefined The capabilities of the promise for which this record provides a reaction handler.
[[Type]] fulfill or reject The [[Type]] is used when [[Handler]] is empty to allow for behaviour specific to the settlement type.
[[Handler]] a JobCallback Record or empty The function that should be applied to the incoming value, and whose return value will govern what happens to the derived promise. If [[Handler]] is empty, a function that depends on the value of [[Type]] will be used instead.

27.2.1.3 CreateResolvingFunctions ( promise )

The abstract operation CreateResolvingFunctions takes argument promise (a Promise) and returns a Record with fields [[Resolve]] (a function object) and [[Reject]] (a function object). It performs the following steps when called:

  1. Let alreadyResolved be the Record { [[Value]]: false }.
  2. Let stepsResolve be the algorithm steps defined in Promise Resolve Functions.
  3. Let lengthResolve be the number of non-optional parameters of the function definition in Promise Resolve Functions.
  4. Let resolve be CreateBuiltinFunction(stepsResolve, lengthResolve, "", « [[Promise]], [[AlreadyResolved]] »).
  5. Set resolve.[[Promise]] to promise.
  6. Set resolve.[[AlreadyResolved]] to alreadyResolved.
  7. Let stepsReject be the algorithm steps defined in Promise Reject Functions.
  8. Let lengthReject be the number of non-optional parameters of the function definition in Promise Reject Functions.
  9. Let reject be CreateBuiltinFunction(stepsReject, lengthReject, "", « [[Promise]], [[AlreadyResolved]] »).
  10. Set reject.[[Promise]] to promise.
  11. Set reject.[[AlreadyResolved]] to alreadyResolved.
  12. Return the Record { [[Resolve]]: resolve, [[Reject]]: reject }.

27.2.1.3.1 Promise Reject Functions

A promise reject function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.

When a promise reject function is called with argument reason, the following steps are taken:

  1. Let F be the active function object.
  2. Assert: F has a [[Promise]] internal slot whose value is an Object.
  3. Let promise be F.[[Promise]].
  4. Let alreadyResolved be F.[[AlreadyResolved]].
  5. If alreadyResolved.[[Value]] is true, return undefined.
  6. Set alreadyResolved.[[Value]] to true.
  7. Perform RejectPromise(promise, reason).
  8. Return undefined.

The "length" property of a promise reject function is 1𝔽.

27.2.1.3.2 Promise Resolve Functions

A promise resolve function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.

When a promise resolve function is called with argument resolution, the following steps are taken:

  1. Let F be the active function object.
  2. Assert: F has a [[Promise]] internal slot whose value is an Object.
  3. Let promise be F.[[Promise]].
  4. Let alreadyResolved be F.[[AlreadyResolved]].
  5. If alreadyResolved.[[Value]] is true, return undefined.
  6. Set alreadyResolved.[[Value]] to true.
  7. If SameValue(resolution, promise) is true, then
    1. Let selfResolutionError be a newly created TypeError object.
    2. Perform RejectPromise(promise, selfResolutionError).
    3. Return undefined.
  8. If resolution is not an Object, then
    1. Perform FulfillPromise(promise, resolution).
    2. Return undefined.
  9. Let then be Completion(Get(resolution, "then")).
  10. If then is an abrupt completion, then
    1. Perform RejectPromise(promise, then.[[Value]]).
    2. Return undefined.
  11. Let thenAction be then.[[Value]].
  12. If IsCallable(thenAction) is false, then
    1. Perform FulfillPromise(promise, resolution).
    2. Return undefined.
  13. Let thenJobCallback be HostMakeJobCallback(thenAction).
  14. Let job be NewPromiseResolveThenableJob(promise, resolution, thenJobCallback).
  15. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
  16. Return undefined.

The "length" property of a promise resolve function is 1𝔽.

27.2.1.4 FulfillPromise ( promise, value )

The abstract operation FulfillPromise takes arguments promise (a Promise) and value (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. Assert: The value of promise.[[PromiseState]] is pending.
  2. Let reactions be promise.[[PromiseFulfillReactions]].
  3. Set promise.[[PromiseResult]] to value.
  4. Set promise.[[PromiseFulfillReactions]] to undefined.
  5. Set promise.[[PromiseRejectReactions]] to undefined.
  6. Set promise.[[PromiseState]] to fulfilled.
  7. Perform TriggerPromiseReactions(reactions, value).
  8. Return unused.

27.2.1.5 NewPromiseCapability ( C )

The abstract operation NewPromiseCapability takes argument C (an ECMAScript language value) and returns either a normal completion containing a PromiseCapability Record or a throw completion. It attempts to use C as a constructor in the fashion of the built-in Promise constructor to create a promise and extract its resolve and reject functions. The promise plus the resolve and reject functions are used to initialize a new PromiseCapability Record. It performs the following steps when called:

  1. If IsConstructor(C) is false, throw a TypeError exception.
  2. NOTE: C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 27.2.3.1).
  3. Let resolvingFunctions be the Record { [[Resolve]]: undefined, [[Reject]]: undefined }.
  4. Let executorClosure be a new Abstract Closure with parameters (resolve, reject) that captures resolvingFunctions and performs the following steps when called:
    1. If resolvingFunctions.[[Resolve]] is not undefined, throw a TypeError exception.
    2. If resolvingFunctions.[[Reject]] is not undefined, throw a TypeError exception.
    3. Set resolvingFunctions.[[Resolve]] to resolve.
    4. Set resolvingFunctions.[[Reject]] to reject.
    5. Return undefined.
  5. Let executor be CreateBuiltinFunction(executorClosure, 2, "", « »).
  6. Let promise be ? Construct(C, « executor »).
  7. If IsCallable(resolvingFunctions.[[Resolve]]) is false, throw a TypeError exception.
  8. If IsCallable(resolvingFunctions.[[Reject]]) is false, throw a TypeError exception.
  9. Return the PromiseCapability Record { [[Promise]]: promise, [[Resolve]]: resolvingFunctions.[[Resolve]], [[Reject]]: resolvingFunctions.[[Reject]] }.
Note

This abstract operation supports Promise subclassing, as it is generic on any constructor that calls a passed executor function argument in the same way as the Promise constructor. It is used to generalize static methods of the Promise constructor to any subclass.

27.2.1.6 IsPromise ( x )

The abstract operation IsPromise takes argument x (an ECMAScript language value) and returns a Boolean. It checks for the promise brand on an object. It performs the following steps when called:

  1. If x is not an Object, return false.
  2. If x does not have a [[PromiseState]] internal slot, return false.
  3. Return true.

27.2.1.7 RejectPromise ( promise, reason )

The abstract operation RejectPromise takes arguments promise (a Promise) and reason (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. Assert: The value of promise.[[PromiseState]] is pending.
  2. Let reactions be promise.[[PromiseRejectReactions]].
  3. Set promise.[[PromiseResult]] to reason.
  4. Set promise.[[PromiseFulfillReactions]] to undefined.
  5. Set promise.[[PromiseRejectReactions]] to undefined.
  6. Set promise.[[PromiseState]] to rejected.
  7. If promise.[[PromiseIsHandled]] is false, perform HostPromiseRejectionTracker(promise, "reject").
  8. Perform TriggerPromiseReactions(reactions, reason).
  9. Return unused.

27.2.1.8 TriggerPromiseReactions ( reactions, argument )

The abstract operation TriggerPromiseReactions takes arguments reactions (a List of PromiseReaction Records) and argument (an ECMAScript language value) and returns unused. It enqueues a new Job for each record in reactions. Each such Job processes the [[Type]] and [[Handler]] of the PromiseReaction Record, and if the [[Handler]] is not empty, calls it passing the given argument. If the [[Handler]] is empty, the behaviour is determined by the [[Type]]. It performs the following steps when called:

  1. For each element reaction of reactions, do
    1. Let job be NewPromiseReactionJob(reaction, argument).
    2. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
  2. Return unused.

27.2.1.9 HostPromiseRejectionTracker ( promise, operation )

The host-defined abstract operation HostPromiseRejectionTracker takes arguments promise (a Promise) and operation ("reject" or "handle") and returns unused. It allows host environments to track promise rejections.

The default implementation of HostPromiseRejectionTracker is to return unused.

Note 1

HostPromiseRejectionTracker is called in two scenarios:

  • When a promise is rejected without any handlers, it is called with its operation argument set to "reject".
  • When a handler is added to a rejected promise for the first time, it is called with its operation argument set to "handle".

A typical implementation of HostPromiseRejectionTracker might try to notify developers of unhandled rejections, while also being careful to notify them if such previous notifications are later invalidated by new handlers being attached.

Note 2

If operation is "handle", an implementation should not hold a reference to promise in a way that would interfere with garbage collection. An implementation may hold a reference to promise if operation is "reject", since it is expected that rejections will be rare and not on hot code paths.

27.2.2 Promise Jobs

27.2.2.1 NewPromiseReactionJob ( reaction, argument )

The abstract operation NewPromiseReactionJob takes arguments reaction (a PromiseReaction Record) and argument (an ECMAScript language value) and returns a Record with fields [[Job]] (a Job Abstract Closure) and [[Realm]] (a Realm Record or null). It returns a new Job Abstract Closure that applies the appropriate handler to the incoming value, and uses the handler's return value to resolve or reject the derived promise associated with that handler. It performs the following steps when called:

  1. Let job be a new Job Abstract Closure with no parameters that captures reaction and argument and performs the following steps when called:
    1. Let promiseCapability be reaction.[[Capability]].
    2. Let type be reaction.[[Type]].
    3. Let handler be reaction.[[Handler]].
    4. If handler is empty, then
      1. If type is fulfill, then
        1. Let handlerResult be NormalCompletion(argument).
      2. Else,
        1. Assert: type is reject.
        2. Let handlerResult be ThrowCompletion(argument).
    5. Else,
      1. Let handlerResult be Completion(HostCallJobCallback(handler, undefined, « argument »)).
    6. If promiseCapability is undefined, then
      1. Assert: handlerResult is not an abrupt completion.
      2. Return empty.
    7. Assert: promiseCapability is a PromiseCapability Record.
    8. If handlerResult is an abrupt completion, then
      1. Return ? Call(promiseCapability.[[Reject]], undefined, « handlerResult.[[Value]] »).
    9. Else,
      1. Return ? Call(promiseCapability.[[Resolve]], undefined, « handlerResult.[[Value]] »).
  2. Let handlerRealm be null.
  3. If reaction.[[Handler]] is not empty, then
    1. Let getHandlerRealmResult be Completion(GetFunctionRealm(reaction.[[Handler]].[[Callback]])).
    2. If getHandlerRealmResult is a normal completion, set handlerRealm to getHandlerRealmResult.[[Value]].
    3. Else, set handlerRealm to the current Realm Record.
    4. NOTE: handlerRealm is never null unless the handler is undefined. When the handler is a revoked Proxy and no ECMAScript code runs, handlerRealm is used to create error objects.
  4. Return the Record { [[Job]]: job, [[Realm]]: handlerRealm }.

27.2.2.2 NewPromiseResolveThenableJob ( promiseToResolve, thenable, then )

The abstract operation NewPromiseResolveThenableJob takes arguments promiseToResolve (a Promise), thenable (an Object), and then (a JobCallback Record) and returns a Record with fields [[Job]] (a Job Abstract Closure) and [[Realm]] (a Realm Record). It performs the following steps when called:

  1. Let job be a new Job Abstract Closure with no parameters that captures promiseToResolve, thenable, and then and performs the following steps when called:
    1. Let resolvingFunctions be CreateResolvingFunctions(promiseToResolve).
    2. Let thenCallResult be Completion(HostCallJobCallback(then, thenable, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
    3. If thenCallResult is an abrupt completion, then
      1. Return ? Call(resolvingFunctions.[[Reject]], undefined, « thenCallResult.[[Value]] »).
    4. Return ? thenCallResult.
  2. Let getThenRealmResult be Completion(GetFunctionRealm(then.[[Callback]])).
  3. If getThenRealmResult is a normal completion, let thenRealm be getThenRealmResult.[[Value]].
  4. Else, let thenRealm be the current Realm Record.
  5. NOTE: thenRealm is never null. When then.[[Callback]] is a revoked Proxy and no code runs, thenRealm is used to create error objects.
  6. Return the Record { [[Job]]: job, [[Realm]]: thenRealm }.
Note

This Job uses the supplied thenable and its then method to resolve the given promise. This process must take place as a Job to ensure that the evaluation of the then method occurs after evaluation of any surrounding code has completed.

27.2.3 The Promise Constructor

The Promise constructor:

  • is %Promise%.
  • is the initial value of the "Promise" property of the global object.
  • creates and initializes a new Promise when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Promise behaviour must include a super call to the Promise constructor to create and initialize the subclass instance with the internal state necessary to support the Promise and Promise.prototype built-in methods.

27.2.3.1 Promise ( executor )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If IsCallable(executor) is false, throw a TypeError exception.
  3. Let promise be ? OrdinaryCreateFromConstructor(NewTarget, "%Promise.prototype%", « [[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]], [[PromiseIsHandled]] »).
  4. Set promise.[[PromiseState]] to pending.
  5. Set promise.[[PromiseFulfillReactions]] to a new empty List.
  6. Set promise.[[PromiseRejectReactions]] to a new empty List.
  7. Set promise.[[PromiseIsHandled]] to false.
  8. Let resolvingFunctions be CreateResolvingFunctions(promise).
  9. Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
  10. If completion is an abrupt completion, then
    1. Perform ? Call(resolvingFunctions.[[Reject]], undefined, « completion.[[Value]] »).
  11. Return promise.
Note

The executor argument must be a function object. It is called for initiating and reporting completion of the possibly deferred action represented by this Promise. The executor is called with two arguments: resolve and reject. These are functions that may be used by the executor function to report eventual completion or failure of the deferred computation. Returning from the executor function does not mean that the deferred action has been completed but only that the request to eventually perform the deferred action has been accepted.

The resolve function that is passed to an executor function accepts a single argument. The executor code may eventually call the resolve function to indicate that it wishes to resolve the associated Promise. The argument passed to the resolve function represents the eventual value of the deferred action and can be either the actual fulfillment value or another promise which will provide the value if it is fulfilled.

The reject function that is passed to an executor function accepts a single argument. The executor code may eventually call the reject function to indicate that the associated Promise is rejected and will never be fulfilled. The argument passed to the reject function is used as the rejection value of the promise. Typically it will be an Error object.

The resolve and reject functions passed to an executor function by the Promise constructor have the capability to actually resolve and reject the associated promise. Subclasses may have different constructor behaviour that passes in customized values for resolve and reject.

27.2.4 Properties of the Promise Constructor

The Promise constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

27.2.4.1 Promise.all ( iterable )

This function returns a new promise which is fulfilled with an array of fulfillment values for the passed promises, or rejects with the reason of the first passed promise that rejects. It resolves all elements of the passed iterable to promises as it runs this algorithm.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Let promiseResolve be Completion(GetPromiseResolve(C)).
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
  5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
  7. Let result be Completion(PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve)).
  8. If result is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
    2. IfAbruptRejectPromise(result, promiseCapability).
  9. Return ? result.
Note

This function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

27.2.4.1.1 GetPromiseResolve ( promiseConstructor )

The abstract operation GetPromiseResolve takes argument promiseConstructor (a constructor) and returns either a normal completion containing a function object or a throw completion. It performs the following steps when called:

  1. Let promiseResolve be ? Get(promiseConstructor, "resolve").
  2. If IsCallable(promiseResolve) is false, throw a TypeError exception.
  3. Return promiseResolve.

27.2.4.1.2 PerformPromiseAll ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseAll takes arguments iteratorRecord (an Iterator Record), constructor (a constructor), resultCapability (a PromiseCapability Record), and promiseResolve (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let values be a new empty List.
  2. Let remainingElementsCount be the Record { [[Value]]: 1 }.
  3. Let index be 0.
  4. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, then
      1. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
      2. If remainingElementsCount.[[Value]] = 0, then
        1. Let valuesArray be CreateArrayFromList(values).
        2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
      3. Return resultCapability.[[Promise]].
    3. Append undefined to values.
    4. Let nextPromise be ? Call(promiseResolve, constructor, « next »).
    5. Let steps be the algorithm steps defined in Promise.all Resolve Element Functions.
    6. Let length be the number of non-optional parameters of the function definition in Promise.all Resolve Element Functions.
    7. Let onFulfilled be CreateBuiltinFunction(steps, length, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
    8. Set onFulfilled.[[AlreadyCalled]] to false.
    9. Set onFulfilled.[[Index]] to index.
    10. Set onFulfilled.[[Values]] to values.
    11. Set onFulfilled.[[Capability]] to resultCapability.
    12. Set onFulfilled.[[RemainingElements]] to remainingElementsCount.
    13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] + 1.
    14. Perform ? Invoke(nextPromise, "then", « onFulfilled, resultCapability.[[Reject]] »).
    15. Set index to index + 1.

27.2.4.1.3 Promise.all Resolve Element Functions

A Promise.all resolve element function is an anonymous built-in function that is used to resolve a specific Promise.all element. Each Promise.all resolve element function has [[Index]], [[Values]], [[Capability]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.

When a Promise.all resolve element function is called with argument x, the following steps are taken:

  1. Let F be the active function object.
  2. If F.[[AlreadyCalled]] is true, return undefined.
  3. Set F.[[AlreadyCalled]] to true.
  4. Let index be F.[[Index]].
  5. Let values be F.[[Values]].
  6. Let promiseCapability be F.[[Capability]].
  7. Let remainingElementsCount be F.[[RemainingElements]].
  8. Set values[index] to x.
  9. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
  10. If remainingElementsCount.[[Value]] = 0, then
    1. Let valuesArray be CreateArrayFromList(values).
    2. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
  11. Return undefined.

The "length" property of a Promise.all resolve element function is 1𝔽.

27.2.4.2 Promise.allSettled ( iterable )

This function returns a promise that is fulfilled with an array of promise state snapshots, but only after all the original promises have settled, i.e. become either fulfilled or rejected. It resolves all elements of the passed iterable to promises as it runs this algorithm.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Let promiseResolve be Completion(GetPromiseResolve(C)).
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
  5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
  7. Let result be Completion(PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve)).
  8. If result is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
    2. IfAbruptRejectPromise(result, promiseCapability).
  9. Return ? result.
Note

This function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

27.2.4.2.1 PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseAllSettled takes arguments iteratorRecord (an Iterator Record), constructor (a constructor), resultCapability (a PromiseCapability Record), and promiseResolve (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let values be a new empty List.
  2. Let remainingElementsCount be the Record { [[Value]]: 1 }.
  3. Let index be 0.
  4. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, then
      1. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
      2. If remainingElementsCount.[[Value]] = 0, then
        1. Let valuesArray be CreateArrayFromList(values).
        2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
      3. Return resultCapability.[[Promise]].
    3. Append undefined to values.
    4. Let nextPromise be ? Call(promiseResolve, constructor, « next »).
    5. Let stepsFulfilled be the algorithm steps defined in Promise.allSettled Resolve Element Functions.
    6. Let lengthFulfilled be the number of non-optional parameters of the function definition in Promise.allSettled Resolve Element Functions.
    7. Let onFulfilled be CreateBuiltinFunction(stepsFulfilled, lengthFulfilled, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
    8. Let alreadyCalled be the Record { [[Value]]: false }.
    9. Set onFulfilled.[[AlreadyCalled]] to alreadyCalled.
    10. Set onFulfilled.[[Index]] to index.
    11. Set onFulfilled.[[Values]] to values.
    12. Set onFulfilled.[[Capability]] to resultCapability.
    13. Set onFulfilled.[[RemainingElements]] to remainingElementsCount.
    14. Let stepsRejected be the algorithm steps defined in Promise.allSettled Reject Element Functions.
    15. Let lengthRejected be the number of non-optional parameters of the function definition in Promise.allSettled Reject Element Functions.
    16. Let onRejected be CreateBuiltinFunction(stepsRejected, lengthRejected, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
    17. Set onRejected.[[AlreadyCalled]] to alreadyCalled.
    18. Set onRejected.[[Index]] to index.
    19. Set onRejected.[[Values]] to values.
    20. Set onRejected.[[Capability]] to resultCapability.
    21. Set onRejected.[[RemainingElements]] to remainingElementsCount.
    22. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] + 1.
    23. Perform ? Invoke(nextPromise, "then", « onFulfilled, onRejected »).
    24. Set index to index + 1.

27.2.4.2.2 Promise.allSettled Resolve Element Functions

A Promise.allSettled resolve element function is an anonymous built-in function that is used to resolve a specific Promise.allSettled element. Each Promise.allSettled resolve element function has [[Index]], [[Values]], [[Capability]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.

When a Promise.allSettled resolve element function is called with argument x, the following steps are taken:

  1. Let F be the active function object.
  2. Let alreadyCalled be F.[[AlreadyCalled]].
  3. If alreadyCalled.[[Value]] is true, return undefined.
  4. Set alreadyCalled.[[Value]] to true.
  5. Let index be F.[[Index]].
  6. Let values be F.[[Values]].
  7. Let promiseCapability be F.[[Capability]].
  8. Let remainingElementsCount be F.[[RemainingElements]].
  9. Let obj be OrdinaryObjectCreate(%Object.prototype%).
  10. Perform ! CreateDataPropertyOrThrow(obj, "status", "fulfilled").
  11. Perform ! CreateDataPropertyOrThrow(obj, "value", x).
  12. Set values[index] to obj.
  13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
  14. If remainingElementsCount.[[Value]] = 0, then
    1. Let valuesArray be CreateArrayFromList(values).
    2. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
  15. Return undefined.

The "length" property of a Promise.allSettled resolve element function is 1𝔽.

27.2.4.2.3 Promise.allSettled Reject Element Functions

A Promise.allSettled reject element function is an anonymous built-in function that is used to reject a specific Promise.allSettled element. Each Promise.allSettled reject element function has [[Index]], [[Values]], [[Capability]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.

When a Promise.allSettled reject element function is called with argument x, the following steps are taken:

  1. Let F be the active function object.
  2. Let alreadyCalled be F.[[AlreadyCalled]].
  3. If alreadyCalled.[[Value]] is true, return undefined.
  4. Set alreadyCalled.[[Value]] to true.
  5. Let index be F.[[Index]].
  6. Let values be F.[[Values]].
  7. Let promiseCapability be F.[[Capability]].
  8. Let remainingElementsCount be F.[[RemainingElements]].
  9. Let obj be OrdinaryObjectCreate(%Object.prototype%).
  10. Perform ! CreateDataPropertyOrThrow(obj, "status", "rejected").
  11. Perform ! CreateDataPropertyOrThrow(obj, "reason", x).
  12. Set values[index] to obj.
  13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
  14. If remainingElementsCount.[[Value]] = 0, then
    1. Let valuesArray be CreateArrayFromList(values).
    2. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
  15. Return undefined.

The "length" property of a Promise.allSettled reject element function is 1𝔽.

27.2.4.3 Promise.any ( iterable )

This function returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an AggregateError holding the rejection reasons if all of the given promises are rejected. It resolves all elements of the passed iterable to promises as it runs this algorithm.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Let promiseResolve be Completion(GetPromiseResolve(C)).
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
  5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
  7. Let result be Completion(PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve)).
  8. If result is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
    2. IfAbruptRejectPromise(result, promiseCapability).
  9. Return ? result.
Note

This function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

27.2.4.3.1 PerformPromiseAny ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseAny takes arguments iteratorRecord (an Iterator Record), constructor (a constructor), resultCapability (a PromiseCapability Record), and promiseResolve (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let errors be a new empty List.
  2. Let remainingElementsCount be the Record { [[Value]]: 1 }.
  3. Let index be 0.
  4. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, then
      1. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
      2. If remainingElementsCount.[[Value]] = 0, then
        1. Let error be a newly created AggregateError object.
        2. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) }).
        3. Return ThrowCompletion(error).
      3. Return resultCapability.[[Promise]].
    3. Append undefined to errors.
    4. Let nextPromise be ? Call(promiseResolve, constructor, « next »).
    5. Let stepsRejected be the algorithm steps defined in Promise.any Reject Element Functions.
    6. Let lengthRejected be the number of non-optional parameters of the function definition in Promise.any Reject Element Functions.
    7. Let onRejected be CreateBuiltinFunction(stepsRejected, lengthRejected, "", « [[AlreadyCalled]], [[Index]], [[Errors]], [[Capability]], [[RemainingElements]] »).
    8. Set onRejected.[[AlreadyCalled]] to false.
    9. Set onRejected.[[Index]] to index.
    10. Set onRejected.[[Errors]] to errors.
    11. Set onRejected.[[Capability]] to resultCapability.
    12. Set onRejected.[[RemainingElements]] to remainingElementsCount.
    13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] + 1.
    14. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], onRejected »).
    15. Set index to index + 1.

27.2.4.3.2 Promise.any Reject Element Functions

A Promise.any reject element function is an anonymous built-in function that is used to reject a specific Promise.any element. Each Promise.any reject element function has [[Index]], [[Errors]], [[Capability]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.

When a Promise.any reject element function is called with argument x, the following steps are taken:

  1. Let F be the active function object.
  2. If F.[[AlreadyCalled]] is true, return undefined.
  3. Set F.[[AlreadyCalled]] to true.
  4. Let index be F.[[Index]].
  5. Let errors be F.[[Errors]].
  6. Let promiseCapability be F.[[Capability]].
  7. Let remainingElementsCount be F.[[RemainingElements]].
  8. Set errors[index] to x.
  9. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
  10. If remainingElementsCount.[[Value]] = 0, then
    1. Let error be a newly created AggregateError object.
    2. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) }).
    3. Return ? Call(promiseCapability.[[Reject]], undefined, « error »).
  11. Return undefined.

The "length" property of a Promise.any reject element function is 1𝔽.

27.2.4.4 Promise.prototype

The initial value of Promise.prototype is the Promise prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

27.2.4.5 Promise.race ( iterable )

This function returns a new promise which is settled in the same way as the first passed promise to settle. It resolves all elements of the passed iterable to promises as it runs this algorithm.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Let promiseResolve be Completion(GetPromiseResolve(C)).
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
  5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
  7. Let result be Completion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve)).
  8. If result is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
    2. IfAbruptRejectPromise(result, promiseCapability).
  9. Return ? result.
Note 1

If the iterable argument yields no values or if none of the promises yielded by iterable ever settle, then the pending promise returned by this method will never be settled.

Note 2

This function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor. It also expects that its this value provides a resolve method.

27.2.4.5.1 PerformPromiseRace ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseRace takes arguments iteratorRecord (an Iterator Record), constructor (a constructor), resultCapability (a PromiseCapability Record), and promiseResolve (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, then
      1. Return resultCapability.[[Promise]].
    3. Let nextPromise be ? Call(promiseResolve, constructor, « next »).
    4. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).

27.2.4.6 Promise.reject ( r )

This function returns a new promise rejected with the passed argument.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
  4. Return promiseCapability.[[Promise]].
Note

This function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

27.2.4.7 Promise.resolve ( x )

This function returns either a new promise resolved with the passed argument, or the argument itself if the argument is a promise produced by this constructor.

  1. Let C be the this value.
  2. If C is not an Object, throw a TypeError exception.
  3. Return ? PromiseResolve(C, x).
Note

This function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

27.2.4.7.1 PromiseResolve ( C, x )

The abstract operation PromiseResolve takes arguments C (a constructor) and x (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or a throw completion. It returns a new promise resolved with x. It performs the following steps when called:

  1. If IsPromise(x) is true, then
    1. Let xConstructor be ? Get(x, "constructor").
    2. If SameValue(xConstructor, C) is true, return x.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »).
  4. Return promiseCapability.[[Promise]].

27.2.4.8 Promise.withResolvers ( )

This function returns an object with three properties: a new promise together with the resolve and reject functions associated with it.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Let obj be OrdinaryObjectCreate(%Object.prototype%).
  4. Perform ! CreateDataPropertyOrThrow(obj, "promise", promiseCapability.[[Promise]]).
  5. Perform ! CreateDataPropertyOrThrow(obj, "resolve", promiseCapability.[[Resolve]]).
  6. Perform ! CreateDataPropertyOrThrow(obj, "reject", promiseCapability.[[Reject]]).
  7. Return obj.

27.2.4.9 get Promise [ @@species ]

Promise[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

Promise prototype methods normally use their this value's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.

27.2.5 Properties of the Promise Prototype Object

The Promise prototype object:

  • is %Promise.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have a [[PromiseState]] internal slot or any of the other internal slots of Promise instances.

27.2.5.1 Promise.prototype.catch ( onRejected )

This method performs the following steps when called:

  1. Let promise be the this value.
  2. Return ? Invoke(promise, "then", « undefined, onRejected »).

27.2.5.2 Promise.prototype.constructor

The initial value of Promise.prototype.constructor is %Promise%.

27.2.5.3 Promise.prototype.finally ( onFinally )

This method performs the following steps when called:

  1. Let promise be the this value.
  2. If promise is not an Object, throw a TypeError exception.
  3. Let C be ? SpeciesConstructor(promise, %Promise%).
  4. Assert: IsConstructor(C) is true.
  5. If IsCallable(onFinally) is false, then
    1. Let thenFinally be onFinally.
    2. Let catchFinally be onFinally.
  6. Else,
    1. Let thenFinallyClosure be a new Abstract Closure with parameters (value) that captures onFinally and C and performs the following steps when called:
      1. Let result be ? Call(onFinally, undefined).
      2. Let p be ? PromiseResolve(C, result).
      3. Let returnValue be a new Abstract Closure with no parameters that captures value and performs the following steps when called:
        1. Return value.
      4. Let valueThunk be CreateBuiltinFunction(returnValue, 0, "", « »).
      5. Return ? Invoke(p, "then", « valueThunk »).
    2. Let thenFinally be CreateBuiltinFunction(thenFinallyClosure, 1, "", « »).
    3. Let catchFinallyClosure be a new Abstract Closure with parameters (reason) that captures onFinally and C and performs the following steps when called:
      1. Let result be ? Call(onFinally, undefined).
      2. Let p be ? PromiseResolve(C, result).
      3. Let throwReason be a new Abstract Closure with no parameters that captures reason and performs the following steps when called:
        1. Return ThrowCompletion(reason).
      4. Let thrower be CreateBuiltinFunction(throwReason, 0, "", « »).
      5. Return ? Invoke(p, "then", « thrower »).
    4. Let catchFinally be CreateBuiltinFunction(catchFinallyClosure, 1, "", « »).
  7. Return ? Invoke(promise, "then", « thenFinally, catchFinally »).

27.2.5.4 Promise.prototype.then ( onFulfilled, onRejected )

This method performs the following steps when called:

  1. Let promise be the this value.
  2. If IsPromise(promise) is false, throw a TypeError exception.
  3. Let C be ? SpeciesConstructor(promise, %Promise%).
  4. Let resultCapability be ? NewPromiseCapability(C).
  5. Return PerformPromiseThen(promise, onFulfilled, onRejected, resultCapability).

27.2.5.4.1 PerformPromiseThen ( promise, onFulfilled, onRejected [ , resultCapability ] )

The abstract operation PerformPromiseThen takes arguments promise (a Promise), onFulfilled (an ECMAScript language value), and onRejected (an ECMAScript language value) and optional argument resultCapability (a PromiseCapability Record) and returns an ECMAScript language value. It performs the “then” operation on promise using onFulfilled and onRejected as its settlement actions. If resultCapability is passed, the result is stored by updating resultCapability's promise. If it is not passed, then PerformPromiseThen is being called by a specification-internal operation where the result does not matter. It performs the following steps when called:

  1. Assert: IsPromise(promise) is true.
  2. If resultCapability is not present, then
    1. Set resultCapability to undefined.
  3. If IsCallable(onFulfilled) is false, then
    1. Let onFulfilledJobCallback be empty.
  4. Else,
    1. Let onFulfilledJobCallback be HostMakeJobCallback(onFulfilled).
  5. If IsCallable(onRejected) is false, then
    1. Let onRejectedJobCallback be empty.
  6. Else,
    1. Let onRejectedJobCallback be HostMakeJobCallback(onRejected).
  7. Let fulfillReaction be the PromiseReaction Record { [[Capability]]: resultCapability, [[Type]]: fulfill, [[Handler]]: onFulfilledJobCallback }.
  8. Let rejectReaction be the PromiseReaction Record { [[Capability]]: resultCapability, [[Type]]: reject, [[Handler]]: onRejectedJobCallback }.
  9. If promise.[[PromiseState]] is pending, then
    1. Append fulfillReaction to promise.[[PromiseFulfillReactions]].
    2. Append rejectReaction to promise.[[PromiseRejectReactions]].
  10. Else if promise.[[PromiseState]] is fulfilled, then
    1. Let value be promise.[[PromiseResult]].
    2. Let fulfillJob be NewPromiseReactionJob(fulfillReaction, value).
    3. Perform HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]]).
  11. Else,
    1. Assert: The value of promise.[[PromiseState]] is rejected.
    2. Let reason be promise.[[PromiseResult]].
    3. If promise.[[PromiseIsHandled]] is false, perform HostPromiseRejectionTracker(promise, "handle").
    4. Let rejectJob be NewPromiseReactionJob(rejectReaction, reason).
    5. Perform HostEnqueuePromiseJob(rejectJob.[[Job]], rejectJob.[[Realm]]).
  12. Set promise.[[PromiseIsHandled]] to true.
  13. If resultCapability is undefined, then
    1. Return undefined.
  14. Else,
    1. Return resultCapability.[[Promise]].

27.2.5.5 Promise.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Promise".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.2.6 Properties of Promise Instances

Promise instances are ordinary objects that inherit properties from the Promise prototype object (the intrinsic, %Promise.prototype%). Promise instances are initially created with the internal slots described in Table 87.

Table 87: Internal Slots of Promise Instances
Internal Slot Type Description
[[PromiseState]] pending, fulfilled, or rejected Governs how a promise will react to incoming calls to its then method.
[[PromiseResult]] an ECMAScript language value The value with which the promise has been fulfilled or rejected, if any. Only meaningful if [[PromiseState]] is not pending.
[[PromiseFulfillReactions]] a List of PromiseReaction Records Records to be processed when/if the promise transitions from the pending state to the fulfilled state.
[[PromiseRejectReactions]] a List of PromiseReaction Records Records to be processed when/if the promise transitions from the pending state to the rejected state.
[[PromiseIsHandled]] a Boolean Indicates whether the promise has ever had a fulfillment or rejection handler; used in unhandled rejection tracking.

27.3 GeneratorFunction Objects

GeneratorFunctions are functions that are usually created by evaluating GeneratorDeclarations, GeneratorExpressions, and GeneratorMethods. They may also be created by calling the %GeneratorFunction% intrinsic.

Figure 6 (Informative): Generator Objects Relationships
A staggering variety of boxes and arrows.

27.3.1 The GeneratorFunction Constructor

The GeneratorFunction constructor:

  • is %GeneratorFunction%.
  • is a subclass of Function.
  • creates and initializes a new GeneratorFunction when called as a function rather than as a constructor. Thus the function call GeneratorFunction (…) is equivalent to the object creation expression new GeneratorFunction (…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified GeneratorFunction behaviour must include a super call to the GeneratorFunction constructor to create and initialize subclass instances with the internal slots necessary for built-in GeneratorFunction behaviour. All ECMAScript syntactic forms for defining generator function objects create direct instances of GeneratorFunction. There is no syntactic means to create instances of GeneratorFunction subclasses.

27.3.1.1 GeneratorFunction ( ...parameterArgs, bodyArg )

The last argument (if any) specifies the body (executable code) of a generator function; any preceding arguments specify formal parameters.

This function performs the following steps when called:

  1. Let C be the active function object.
  2. If bodyArg is not present, set bodyArg to the empty String.
  3. Return ? CreateDynamicFunction(C, NewTarget, generator, parameterArgs, bodyArg).
Note

See NOTE for 20.2.1.1.

27.3.2 Properties of the GeneratorFunction Constructor

The GeneratorFunction constructor:

  • is a standard built-in function object that inherits from the Function constructor.
  • has a [[Prototype]] internal slot whose value is %Function%.
  • has a "length" property whose value is 1𝔽.
  • has a "name" property whose value is "GeneratorFunction".
  • has the following properties:

27.3.2.1 GeneratorFunction.prototype

The initial value of GeneratorFunction.prototype is the GeneratorFunction prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

27.3.3 Properties of the GeneratorFunction Prototype Object

The GeneratorFunction prototype object:

27.3.3.1 GeneratorFunction.prototype.constructor

The initial value of GeneratorFunction.prototype.constructor is %GeneratorFunction%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.3.3.2 GeneratorFunction.prototype.prototype

The initial value of GeneratorFunction.prototype.prototype is the Generator prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.3.3.3 GeneratorFunction.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "GeneratorFunction".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.3.4 GeneratorFunction Instances

Every GeneratorFunction instance is an ECMAScript function object and has the internal slots listed in Table 30. The value of the [[IsClassConstructor]] internal slot for all such instances is false.

Each GeneratorFunction instance has the following own properties:

27.3.4.1 length

The specification for the "length" property of Function instances given in 20.2.4.1 also applies to GeneratorFunction instances.

27.3.4.2 name

The specification for the "name" property of Function instances given in 20.2.4.2 also applies to GeneratorFunction instances.

27.3.4.3 prototype

Whenever a GeneratorFunction instance is created another ordinary object is also created and is the initial value of the generator function's "prototype" property. The value of the prototype property is used to initialize the [[Prototype]] internal slot of a newly created Generator when the generator function object is invoked using [[Call]].

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Unlike Function instances, the object that is the value of a GeneratorFunction's "prototype" property does not have a "constructor" property whose value is the GeneratorFunction instance.

27.4 AsyncGeneratorFunction Objects

AsyncGeneratorFunctions are functions that are usually created by evaluating AsyncGeneratorDeclaration, AsyncGeneratorExpression, and AsyncGeneratorMethod syntactic productions. They may also be created by calling the %AsyncGeneratorFunction% intrinsic.

27.4.1 The AsyncGeneratorFunction Constructor

The AsyncGeneratorFunction constructor:

  • is %AsyncGeneratorFunction%.
  • is a subclass of Function.
  • creates and initializes a new AsyncGeneratorFunction when called as a function rather than as a constructor. Thus the function call AsyncGeneratorFunction (...) is equivalent to the object creation expression new AsyncGeneratorFunction (...) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified AsyncGeneratorFunction behaviour must include a super call to the AsyncGeneratorFunction constructor to create and initialize subclass instances with the internal slots necessary for built-in AsyncGeneratorFunction behaviour. All ECMAScript syntactic forms for defining async generator function objects create direct instances of AsyncGeneratorFunction. There is no syntactic means to create instances of AsyncGeneratorFunction subclasses.

27.4.1.1 AsyncGeneratorFunction ( ...parameterArgs, bodyArg )

The last argument (if any) specifies the body (executable code) of an async generator function; any preceding arguments specify formal parameters.

This function performs the following steps when called:

  1. Let C be the active function object.
  2. If bodyArg is not present, set bodyArg to the empty String.
  3. Return ? CreateDynamicFunction(C, NewTarget, async-generator, parameterArgs, bodyArg).
Note

See NOTE for 20.2.1.1.

27.4.2 Properties of the AsyncGeneratorFunction Constructor

The AsyncGeneratorFunction constructor:

  • is a standard built-in function object that inherits from the Function constructor.
  • has a [[Prototype]] internal slot whose value is %Function%.
  • has a "length" property whose value is 1𝔽.
  • has a "name" property whose value is "AsyncGeneratorFunction".
  • has the following properties:

27.4.2.1 AsyncGeneratorFunction.prototype

The initial value of AsyncGeneratorFunction.prototype is the AsyncGeneratorFunction prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

27.4.3 Properties of the AsyncGeneratorFunction Prototype Object

The AsyncGeneratorFunction prototype object:

27.4.3.1 AsyncGeneratorFunction.prototype.constructor

The initial value of AsyncGeneratorFunction.prototype.constructor is %AsyncGeneratorFunction%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.4.3.2 AsyncGeneratorFunction.prototype.prototype

The initial value of AsyncGeneratorFunction.prototype.prototype is the AsyncGenerator prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.4.3.3 AsyncGeneratorFunction.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "AsyncGeneratorFunction".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.4.4 AsyncGeneratorFunction Instances

Every AsyncGeneratorFunction instance is an ECMAScript function object and has the internal slots listed in Table 30. The value of the [[IsClassConstructor]] internal slot for all such instances is false.

Each AsyncGeneratorFunction instance has the following own properties:

27.4.4.1 length

The value of the "length" property is an integral Number that indicates the typical number of arguments expected by the AsyncGeneratorFunction. However, the language permits the function to be invoked with some other number of arguments. The behaviour of an AsyncGeneratorFunction when invoked on a number of arguments other than the number specified by its "length" property depends on the function.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.4.4.2 name

The specification for the "name" property of Function instances given in 20.2.4.2 also applies to AsyncGeneratorFunction instances.

27.4.4.3 prototype

Whenever an AsyncGeneratorFunction instance is created, another ordinary object is also created and is the initial value of the async generator function's "prototype" property. The value of the prototype property is used to initialize the [[Prototype]] internal slot of a newly created AsyncGenerator when the generator function object is invoked using [[Call]].

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Unlike function instances, the object that is the value of an AsyncGeneratorFunction's "prototype" property does not have a "constructor" property whose value is the AsyncGeneratorFunction instance.

27.5 Generator Objects

A Generator is an instance of a generator function and conforms to both the Iterator and Iterable interfaces.

Generator instances directly inherit properties from the object that is the initial value of the "prototype" property of the Generator function that created the instance. Generator instances indirectly inherit properties from the Generator Prototype intrinsic, %GeneratorFunction.prototype.prototype%.

27.5.1 Properties of the Generator Prototype Object

The Generator prototype object:

  • is %GeneratorFunction.prototype.prototype%.
  • is an ordinary object.
  • is not a Generator instance and does not have a [[GeneratorState]] internal slot.
  • has a [[Prototype]] internal slot whose value is %IteratorPrototype%.
  • has properties that are indirectly inherited by all Generator instances.

27.5.1.1 Generator.prototype.constructor

The initial value of Generator.prototype.constructor is %GeneratorFunction.prototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.5.1.2 Generator.prototype.next ( value )

  1. Return ? GeneratorResume(this value, value, empty).

27.5.1.3 Generator.prototype.return ( value )

This method performs the following steps when called:

  1. Let g be the this value.
  2. Let C be Completion Record { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
  3. Return ? GeneratorResumeAbrupt(g, C, empty).

27.5.1.4 Generator.prototype.throw ( exception )

This method performs the following steps when called:

  1. Let g be the this value.
  2. Let C be ThrowCompletion(exception).
  3. Return ? GeneratorResumeAbrupt(g, C, empty).

27.5.1.5 Generator.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Generator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.5.2 Properties of Generator Instances

Generator instances are initially created with the internal slots described in Table 88.

Table 88: Internal Slots of Generator Instances
Internal Slot Type Description
[[GeneratorState]] undefined, suspended-start, suspended-yield, executing, or completed The current execution state of the generator.
[[GeneratorContext]] an execution context The execution context that is used when executing the code of this generator.
[[GeneratorBrand]] a String or empty A brand used to distinguish different kinds of generators. The [[GeneratorBrand]] of generators declared by ECMAScript source text is always empty.

27.5.3 Generator Abstract Operations

27.5.3.1 GeneratorStart ( generator, generatorBody )

The abstract operation GeneratorStart takes arguments generator (a Generator) and generatorBody (a FunctionBody Parse Node or an Abstract Closure with no parameters) and returns unused. It performs the following steps when called:

  1. Assert: The value of generator.[[GeneratorState]] is undefined.
  2. Let genContext be the running execution context.
  3. Set the Generator component of genContext to generator.
  4. Let closure be a new Abstract Closure with no parameters that captures generatorBody and performs the following steps when called:
    1. Let acGenContext be the running execution context.
    2. Let acGenerator be the Generator component of acGenContext.
    3. If generatorBody is a Parse Node, then
      1. Let result be Completion(Evaluation of generatorBody).
    4. Else,
      1. Assert: generatorBody is an Abstract Closure with no parameters.
      2. Let result be generatorBody().
    5. Assert: If we return here, the generator either threw an exception or performed either an implicit or explicit return.
    6. Remove acGenContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
    7. Set acGenerator.[[GeneratorState]] to completed.
    8. NOTE: Once a generator enters the completed state it never leaves it and its associated execution context is never resumed. Any execution state associated with acGenerator can be discarded at this point.
    9. If result is a normal completion, then
      1. Let resultValue be undefined.
    10. Else if result is a return completion, then
      1. Let resultValue be result.[[Value]].
    11. Else,
      1. Assert: result is a throw completion.
      2. Return ? result.
    12. Return CreateIterResultObject(resultValue, true).
  5. Set the code evaluation state of genContext such that when evaluation is resumed for that execution context, closure will be called with no arguments.
  6. Set generator.[[GeneratorContext]] to genContext.
  7. Set generator.[[GeneratorState]] to suspended-start.
  8. Return unused.

27.5.3.2 GeneratorValidate ( generator, generatorBrand )

The abstract operation GeneratorValidate takes arguments generator (an ECMAScript language value) and generatorBrand (a String or empty) and returns either a normal completion containing one of suspended-start, suspended-yield, or completed, or a throw completion. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(generator, [[GeneratorState]]).
  2. Perform ? RequireInternalSlot(generator, [[GeneratorBrand]]).
  3. If generator.[[GeneratorBrand]] is not generatorBrand, throw a TypeError exception.
  4. Assert: generator also has a [[GeneratorContext]] internal slot.
  5. Let state be generator.[[GeneratorState]].
  6. If state is executing, throw a TypeError exception.
  7. Return state.

27.5.3.3 GeneratorResume ( generator, value, generatorBrand )

The abstract operation GeneratorResume takes arguments generator (an ECMAScript language value), value (an ECMAScript language value or empty), and generatorBrand (a String or empty) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let state be ? GeneratorValidate(generator, generatorBrand).
  2. If state is completed, return CreateIterResultObject(undefined, true).
  3. Assert: state is either suspended-start or suspended-yield.
  4. Let genContext be generator.[[GeneratorContext]].
  5. Let methodContext be the running execution context.
  6. Suspend methodContext.
  7. Set generator.[[GeneratorState]] to executing.
  8. Push genContext onto the execution context stack; genContext is now the running execution context.
  9. Resume the suspended evaluation of genContext using NormalCompletion(value) as the result of the operation that suspended it. Let result be the value returned by the resumed computation.
  10. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context.
  11. Return ? result.

27.5.3.4 GeneratorResumeAbrupt ( generator, abruptCompletion, generatorBrand )

The abstract operation GeneratorResumeAbrupt takes arguments generator (an ECMAScript language value), abruptCompletion (a return completion or a throw completion), and generatorBrand (a String or empty) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let state be ? GeneratorValidate(generator, generatorBrand).
  2. If state is suspended-start, then
    1. Set generator.[[GeneratorState]] to completed.
    2. NOTE: Once a generator enters the completed state it never leaves it and its associated execution context is never resumed. Any execution state associated with generator can be discarded at this point.
    3. Set state to completed.
  3. If state is completed, then
    1. If abruptCompletion is a return completion, then
      1. Return CreateIterResultObject(abruptCompletion.[[Value]], true).
    2. Return ? abruptCompletion.
  4. Assert: state is suspended-yield.
  5. Let genContext be generator.[[GeneratorContext]].
  6. Let methodContext be the running execution context.
  7. Suspend methodContext.
  8. Set generator.[[GeneratorState]] to executing.
  9. Push genContext onto the execution context stack; genContext is now the running execution context.
  10. Resume the suspended evaluation of genContext using abruptCompletion as the result of the operation that suspended it. Let result be the Completion Record returned by the resumed computation.
  11. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context.
  12. Return ? result.

27.5.3.5 GetGeneratorKind ( )

The abstract operation GetGeneratorKind takes no arguments and returns non-generator, sync, or async. It performs the following steps when called:

  1. Let genContext be the running execution context.
  2. If genContext does not have a Generator component, return non-generator.
  3. Let generator be the Generator component of genContext.
  4. If generator has an [[AsyncGeneratorState]] internal slot, return async.
  5. Else, return sync.

27.5.3.6 GeneratorYield ( iterNextObj )

The abstract operation GeneratorYield takes argument iterNextObj (an Object that conforms to the IteratorResult interface) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. Let genContext be the running execution context.
  2. Assert: genContext is the execution context of a generator.
  3. Let generator be the value of the Generator component of genContext.
  4. Assert: GetGeneratorKind() is sync.
  5. Set generator.[[GeneratorState]] to suspended-yield.
  6. Remove genContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
  7. Let callerContext be the running execution context.
  8. Resume callerContext passing NormalCompletion(iterNextObj). If genContext is ever resumed again, let resumptionValue be the Completion Record with which it is resumed.
  9. Assert: If control reaches here, then genContext is the running execution context again.
  10. Return resumptionValue.

27.5.3.7 Yield ( value )

The abstract operation Yield takes argument value (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. Let generatorKind be GetGeneratorKind().
  2. If generatorKind is async, return ? AsyncGeneratorYield(? Await(value)).
  3. Otherwise, return ? GeneratorYield(CreateIterResultObject(value, false)).

27.5.3.8 CreateIteratorFromClosure ( closure, generatorBrand, generatorPrototype )

The abstract operation CreateIteratorFromClosure takes arguments closure (an Abstract Closure with no parameters), generatorBrand (a String or empty), and generatorPrototype (an Object) and returns a Generator. It performs the following steps when called:

  1. NOTE: closure can contain uses of the Yield operation to yield an IteratorResult object.
  2. Let internalSlotsList be « [[GeneratorState]], [[GeneratorContext]], [[GeneratorBrand]] ».
  3. Let generator be OrdinaryObjectCreate(generatorPrototype, internalSlotsList).
  4. Set generator.[[GeneratorBrand]] to generatorBrand.
  5. Set generator.[[GeneratorState]] to undefined.
  6. Let callerContext be the running execution context.
  7. Let calleeContext be a new execution context.
  8. Set the Function of calleeContext to null.
  9. Set the Realm of calleeContext to the current Realm Record.
  10. Set the ScriptOrModule of calleeContext to callerContext's ScriptOrModule.
  11. If callerContext is not already suspended, suspend callerContext.
  12. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
  13. Perform GeneratorStart(generator, closure).
  14. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
  15. Return generator.

27.6 AsyncGenerator Objects

An AsyncGenerator is an instance of an async generator function and conforms to both the AsyncIterator and AsyncIterable interfaces.

AsyncGenerator instances directly inherit properties from the object that is the initial value of the "prototype" property of the AsyncGenerator function that created the instance. AsyncGenerator instances indirectly inherit properties from the AsyncGenerator Prototype intrinsic, %AsyncGeneratorFunction.prototype.prototype%.

27.6.1 Properties of the AsyncGenerator Prototype Object

The AsyncGenerator prototype object:

  • is %AsyncGeneratorFunction.prototype.prototype%.
  • is an ordinary object.
  • is not an AsyncGenerator instance and does not have an [[AsyncGeneratorState]] internal slot.
  • has a [[Prototype]] internal slot whose value is %AsyncIteratorPrototype%.
  • has properties that are indirectly inherited by all AsyncGenerator instances.

27.6.1.1 AsyncGenerator.prototype.constructor

The initial value of AsyncGenerator.prototype.constructor is %AsyncGeneratorFunction.prototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.6.1.2 AsyncGenerator.prototype.next ( value )

  1. Let generator be the this value.
  2. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  3. Let result be Completion(AsyncGeneratorValidate(generator, empty)).
  4. IfAbruptRejectPromise(result, promiseCapability).
  5. Let state be generator.[[AsyncGeneratorState]].
  6. If state is completed, then
    1. Let iteratorResult be CreateIterResultObject(undefined, true).
    2. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »).
    3. Return promiseCapability.[[Promise]].
  7. Let completion be NormalCompletion(value).
  8. Perform AsyncGeneratorEnqueue(generator, completion, promiseCapability).
  9. If state is either suspended-start or suspended-yield, then
    1. Perform AsyncGeneratorResume(generator, completion).
  10. Else,
    1. Assert: state is either executing or awaiting-return.
  11. Return promiseCapability.[[Promise]].

27.6.1.3 AsyncGenerator.prototype.return ( value )

  1. Let generator be the this value.
  2. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  3. Let result be Completion(AsyncGeneratorValidate(generator, empty)).
  4. IfAbruptRejectPromise(result, promiseCapability).
  5. Let completion be Completion Record { [[Type]]: return, [[Value]]: value, [[Target]]: empty }.
  6. Perform AsyncGeneratorEnqueue(generator, completion, promiseCapability).
  7. Let state be generator.[[AsyncGeneratorState]].
  8. If state is either suspended-start or completed, then
    1. Set generator.[[AsyncGeneratorState]] to awaiting-return.
    2. Perform ! AsyncGeneratorAwaitReturn(generator).
  9. Else if state is suspended-yield, then
    1. Perform AsyncGeneratorResume(generator, completion).
  10. Else,
    1. Assert: state is either executing or awaiting-return.
  11. Return promiseCapability.[[Promise]].

27.6.1.4 AsyncGenerator.prototype.throw ( exception )

  1. Let generator be the this value.
  2. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  3. Let result be Completion(AsyncGeneratorValidate(generator, empty)).
  4. IfAbruptRejectPromise(result, promiseCapability).
  5. Let state be generator.[[AsyncGeneratorState]].
  6. If state is suspended-start, then
    1. Set generator.[[AsyncGeneratorState]] to completed.
    2. Set state to completed.
  7. If state is completed, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « exception »).
    2. Return promiseCapability.[[Promise]].
  8. Let completion be ThrowCompletion(exception).
  9. Perform AsyncGeneratorEnqueue(generator, completion, promiseCapability).
  10. If state is suspended-yield, then
    1. Perform AsyncGeneratorResume(generator, completion).
  11. Else,
    1. Assert: state is either executing or awaiting-return.
  12. Return promiseCapability.[[Promise]].

27.6.1.5 AsyncGenerator.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "AsyncGenerator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.6.2 Properties of AsyncGenerator Instances

AsyncGenerator instances are initially created with the internal slots described below:

Table 89: Internal Slots of AsyncGenerator Instances
Internal Slot Type Description
[[AsyncGeneratorState]] undefined, suspended-start, suspended-yield, executing, awaiting-return, or completed The current execution state of the async generator.
[[AsyncGeneratorContext]] an execution context The execution context that is used when executing the code of this async generator.
[[AsyncGeneratorQueue]] a List of AsyncGeneratorRequest Records Records which represent requests to resume the async generator. Except during state transitions, it is non-empty if and only if [[AsyncGeneratorState]] is either executing or awaiting-return.
[[GeneratorBrand]] a String or empty A brand used to distinguish different kinds of async generators. The [[GeneratorBrand]] of async generators declared by ECMAScript source text is always empty.

27.6.3 AsyncGenerator Abstract Operations

27.6.3.1 AsyncGeneratorRequest Records

An AsyncGeneratorRequest is a Record value used to store information about how an async generator should be resumed and contains capabilities for fulfilling or rejecting the corresponding promise.

They have the following fields:

Table 90: AsyncGeneratorRequest Record Fields
Field Name Value Meaning
[[Completion]] a Completion Record The Completion Record which should be used to resume the async generator.
[[Capability]] a PromiseCapability Record The promise capabilities associated with this request.

27.6.3.2 AsyncGeneratorStart ( generator, generatorBody )

The abstract operation AsyncGeneratorStart takes arguments generator (an AsyncGenerator) and generatorBody (a FunctionBody Parse Node or an Abstract Closure with no parameters) and returns unused. It performs the following steps when called:

  1. Assert: generator.[[AsyncGeneratorState]] is undefined.
  2. Let genContext be the running execution context.
  3. Set the Generator component of genContext to generator.
  4. Let closure be a new Abstract Closure with no parameters that captures generatorBody and performs the following steps when called:
    1. Let acGenContext be the running execution context.
    2. Let acGenerator be the Generator component of acGenContext.
    3. If generatorBody is a Parse Node, then
      1. Let result be Completion(Evaluation of generatorBody).
    4. Else,
      1. Assert: generatorBody is an Abstract Closure with no parameters.
      2. Let result be Completion(generatorBody()).
    5. Assert: If we return here, the async generator either threw an exception or performed either an implicit or explicit return.
    6. Remove acGenContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
    7. Set acGenerator.[[AsyncGeneratorState]] to completed.
    8. If result is a normal completion, set result to NormalCompletion(undefined).
    9. If result is a return completion, set result to NormalCompletion(result.[[Value]]).
    10. Perform AsyncGeneratorCompleteStep(acGenerator, result, true).
    11. Perform AsyncGeneratorDrainQueue(acGenerator).
    12. Return undefined.
  5. Set the code evaluation state of genContext such that when evaluation is resumed for that execution context, closure will be called with no arguments.
  6. Set generator.[[AsyncGeneratorContext]] to genContext.
  7. Set generator.[[AsyncGeneratorState]] to suspended-start.
  8. Set generator.[[AsyncGeneratorQueue]] to a new empty List.
  9. Return unused.

27.6.3.3 AsyncGeneratorValidate ( generator, generatorBrand )

The abstract operation AsyncGeneratorValidate takes arguments generator (an ECMAScript language value) and generatorBrand (a String or empty) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(generator, [[AsyncGeneratorContext]]).
  2. Perform ? RequireInternalSlot(generator, [[AsyncGeneratorState]]).
  3. Perform ? RequireInternalSlot(generator, [[AsyncGeneratorQueue]]).
  4. If generator.[[GeneratorBrand]] is not generatorBrand, throw a TypeError exception.
  5. Return unused.

27.6.3.4 AsyncGeneratorEnqueue ( generator, completion, promiseCapability )

The abstract operation AsyncGeneratorEnqueue takes arguments generator (an AsyncGenerator), completion (a Completion Record), and promiseCapability (a PromiseCapability Record) and returns unused. It performs the following steps when called:

  1. Let request be AsyncGeneratorRequest { [[Completion]]: completion, [[Capability]]: promiseCapability }.
  2. Append request to generator.[[AsyncGeneratorQueue]].
  3. Return unused.

27.6.3.5 AsyncGeneratorCompleteStep ( generator, completion, done [ , realm ] )

The abstract operation AsyncGeneratorCompleteStep takes arguments generator (an AsyncGenerator), completion (a Completion Record), and done (a Boolean) and optional argument realm (a Realm Record) and returns unused. It performs the following steps when called:

  1. Assert: generator.[[AsyncGeneratorQueue]] is not empty.
  2. Let next be the first element of generator.[[AsyncGeneratorQueue]].
  3. Remove the first element from generator.[[AsyncGeneratorQueue]].
  4. Let promiseCapability be next.[[Capability]].
  5. Let value be completion.[[Value]].
  6. If completion is a throw completion, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « value »).
  7. Else,
    1. Assert: completion is a normal completion.
    2. If realm is present, then
      1. Let oldRealm be the running execution context's Realm.
      2. Set the running execution context's Realm to realm.
      3. Let iteratorResult be CreateIterResultObject(value, done).
      4. Set the running execution context's Realm to oldRealm.
    3. Else,
      1. Let iteratorResult be CreateIterResultObject(value, done).
    4. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »).
  8. Return unused.

27.6.3.6 AsyncGeneratorResume ( generator, completion )

The abstract operation AsyncGeneratorResume takes arguments generator (an AsyncGenerator) and completion (a Completion Record) and returns unused. It performs the following steps when called:

  1. Assert: generator.[[AsyncGeneratorState]] is either suspended-start or suspended-yield.
  2. Let genContext be generator.[[AsyncGeneratorContext]].
  3. Let callerContext be the running execution context.
  4. Suspend callerContext.
  5. Set generator.[[AsyncGeneratorState]] to executing.
  6. Push genContext onto the execution context stack; genContext is now the running execution context.
  7. Resume the suspended evaluation of genContext using completion as the result of the operation that suspended it. Let result be the Completion Record returned by the resumed computation.
  8. Assert: result is never an abrupt completion.
  9. Assert: When we return here, genContext has already been removed from the execution context stack and callerContext is the currently running execution context.
  10. Return unused.

27.6.3.7 AsyncGeneratorUnwrapYieldResumption ( resumptionValue )

The abstract operation AsyncGeneratorUnwrapYieldResumption takes argument resumptionValue (a Completion Record) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. If resumptionValue is not a return completion, return ? resumptionValue.
  2. Let awaited be Completion(Await(resumptionValue.[[Value]])).
  3. If awaited is a throw completion, return ? awaited.
  4. Assert: awaited is a normal completion.
  5. Return Completion Record { [[Type]]: return, [[Value]]: awaited.[[Value]], [[Target]]: empty }.

27.6.3.8 AsyncGeneratorYield ( value )

The abstract operation AsyncGeneratorYield takes argument value (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. Let genContext be the running execution context.
  2. Assert: genContext is the execution context of a generator.
  3. Let generator be the value of the Generator component of genContext.
  4. Assert: GetGeneratorKind() is async.
  5. Let completion be NormalCompletion(value).
  6. Assert: The execution context stack has at least two elements.
  7. Let previousContext be the second to top element of the execution context stack.
  8. Let previousRealm be previousContext's Realm.
  9. Perform AsyncGeneratorCompleteStep(generator, completion, false, previousRealm).
  10. Let queue be generator.[[AsyncGeneratorQueue]].
  11. If queue is not empty, then
    1. NOTE: Execution continues without suspending the generator.
    2. Let toYield be the first element of queue.
    3. Let resumptionValue be Completion(toYield.[[Completion]]).
    4. Return ? AsyncGeneratorUnwrapYieldResumption(resumptionValue).
  12. Else,
    1. Set generator.[[AsyncGeneratorState]] to suspended-yield.
    2. Remove genContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
    3. Let callerContext be the running execution context.
    4. Resume callerContext passing undefined. If genContext is ever resumed again, let resumptionValue be the Completion Record with which it is resumed.
    5. Assert: If control reaches here, then genContext is the running execution context again.
    6. Return ? AsyncGeneratorUnwrapYieldResumption(resumptionValue).

27.6.3.9 AsyncGeneratorAwaitReturn ( generator )

The abstract operation AsyncGeneratorAwaitReturn takes argument generator (an AsyncGenerator) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let queue be generator.[[AsyncGeneratorQueue]].
  2. Assert: queue is not empty.
  3. Let next be the first element of queue.
  4. Let completion be Completion(next.[[Completion]]).
  5. Assert: completion is a return completion.
  6. Let promise be ? PromiseResolve(%Promise%, completion.[[Value]]).
  7. Let fulfilledClosure be a new Abstract Closure with parameters (value) that captures generator and performs the following steps when called:
    1. Set generator.[[AsyncGeneratorState]] to completed.
    2. Let result be NormalCompletion(value).
    3. Perform AsyncGeneratorCompleteStep(generator, result, true).
    4. Perform AsyncGeneratorDrainQueue(generator).
    5. Return undefined.
  8. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
  9. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures generator and performs the following steps when called:
    1. Set generator.[[AsyncGeneratorState]] to completed.
    2. Let result be ThrowCompletion(reason).
    3. Perform AsyncGeneratorCompleteStep(generator, result, true).
    4. Perform AsyncGeneratorDrainQueue(generator).
    5. Return undefined.
  10. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
  11. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
  12. Return unused.

27.6.3.10 AsyncGeneratorDrainQueue ( generator )

The abstract operation AsyncGeneratorDrainQueue takes argument generator (an AsyncGenerator) and returns unused. It drains the generator's AsyncGeneratorQueue until it encounters an AsyncGeneratorRequest which holds a return completion. It performs the following steps when called:

  1. Assert: generator.[[AsyncGeneratorState]] is completed.
  2. Let queue be generator.[[AsyncGeneratorQueue]].
  3. If queue is empty, return unused.
  4. Let done be false.
  5. Repeat, while done is false,
    1. Let next be the first element of queue.
    2. Let completion be Completion(next.[[Completion]]).
    3. If completion is a return completion, then
      1. Set generator.[[AsyncGeneratorState]] to awaiting-return.
      2. Perform ! AsyncGeneratorAwaitReturn(generator).
      3. Set done to true.
    4. Else,
      1. If completion is a normal completion, then
        1. Set completion to NormalCompletion(undefined).
      2. Perform AsyncGeneratorCompleteStep(generator, completion, true).
      3. If queue is empty, set done to true.
  6. Return unused.

27.6.3.11 CreateAsyncIteratorFromClosure ( closure, generatorBrand, generatorPrototype )

The abstract operation CreateAsyncIteratorFromClosure takes arguments closure (an Abstract Closure with no parameters), generatorBrand (a String or empty), and generatorPrototype (an Object) and returns an AsyncGenerator. It performs the following steps when called:

  1. NOTE: closure can contain uses of the Await operation and uses of the Yield operation to yield an IteratorResult object.
  2. Let internalSlotsList be « [[AsyncGeneratorState]], [[AsyncGeneratorContext]], [[AsyncGeneratorQueue]], [[GeneratorBrand]] ».
  3. Let generator be OrdinaryObjectCreate(generatorPrototype, internalSlotsList).
  4. Set generator.[[GeneratorBrand]] to generatorBrand.
  5. Set generator.[[AsyncGeneratorState]] to undefined.
  6. Let callerContext be the running execution context.
  7. Let calleeContext be a new execution context.
  8. Set the Function of calleeContext to null.
  9. Set the Realm of calleeContext to the current Realm Record.
  10. Set the ScriptOrModule of calleeContext to callerContext's ScriptOrModule.
  11. If callerContext is not already suspended, suspend callerContext.
  12. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
  13. Perform AsyncGeneratorStart(generator, closure).
  14. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
  15. Return generator.

27.7 AsyncFunction Objects

AsyncFunctions are functions that are usually created by evaluating AsyncFunctionDeclarations, AsyncFunctionExpressions, AsyncMethods, and AsyncArrowFunctions. They may also be created by calling the %AsyncFunction% intrinsic.

27.7.1 The AsyncFunction Constructor

The AsyncFunction constructor:

  • is %AsyncFunction%.
  • is a subclass of Function.
  • creates and initializes a new AsyncFunction when called as a function rather than as a constructor. Thus the function call AsyncFunction(…) is equivalent to the object creation expression new AsyncFunction(…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified AsyncFunction behaviour must include a super call to the AsyncFunction constructor to create and initialize a subclass instance with the internal slots necessary for built-in async function behaviour. All ECMAScript syntactic forms for defining async function objects create direct instances of AsyncFunction. There is no syntactic means to create instances of AsyncFunction subclasses.

27.7.1.1 AsyncFunction ( ...parameterArgs, bodyArg )

The last argument (if any) specifies the body (executable code) of an async function. Any preceding arguments specify formal parameters.

This function performs the following steps when called:

  1. Let C be the active function object.
  2. If bodyArg is not present, set bodyArg to the empty String.
  3. Return ? CreateDynamicFunction(C, NewTarget, async, parameterArgs, bodyArg).
Note
See NOTE for 20.2.1.1.

27.7.2 Properties of the AsyncFunction Constructor

The AsyncFunction constructor:

  • is a standard built-in function object that inherits from the Function constructor.
  • has a [[Prototype]] internal slot whose value is %Function%.
  • has a "length" property whose value is 1𝔽.
  • has a "name" property whose value is "AsyncFunction".
  • has the following properties:

27.7.2.1 AsyncFunction.prototype

The initial value of AsyncFunction.prototype is the AsyncFunction prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

27.7.3 Properties of the AsyncFunction Prototype Object

The AsyncFunction prototype object:

27.7.3.1 AsyncFunction.prototype.constructor

The initial value of AsyncFunction.prototype.constructor is %AsyncFunction%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.7.3.2 AsyncFunction.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "AsyncFunction".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.7.4 AsyncFunction Instances

Every AsyncFunction instance is an ECMAScript function object and has the internal slots listed in Table 30. The value of the [[IsClassConstructor]] internal slot for all such instances is false. AsyncFunction instances are not constructors and do not have a [[Construct]] internal method. AsyncFunction instances do not have a prototype property as they are not constructible.

Each AsyncFunction instance has the following own properties:

27.7.4.1 length

The specification for the "length" property of Function instances given in 20.2.4.1 also applies to AsyncFunction instances.

27.7.4.2 name

The specification for the "name" property of Function instances given in 20.2.4.2 also applies to AsyncFunction instances.

27.7.5 Async Functions Abstract Operations

27.7.5.1 AsyncFunctionStart ( promiseCapability, asyncFunctionBody )

The abstract operation AsyncFunctionStart takes arguments promiseCapability (a PromiseCapability Record) and asyncFunctionBody (a FunctionBody Parse Node or an ExpressionBody Parse Node) and returns unused. It performs the following steps when called:

  1. Let runningContext be the running execution context.
  2. Let asyncContext be a copy of runningContext.
  3. NOTE: Copying the execution state is required for AsyncBlockStart to resume its execution. It is ill-defined to resume a currently executing context.
  4. Perform AsyncBlockStart(promiseCapability, asyncFunctionBody, asyncContext).
  5. Return unused.

27.7.5.2 AsyncBlockStart ( promiseCapability, asyncBody, asyncContext )

The abstract operation AsyncBlockStart takes arguments promiseCapability (a PromiseCapability Record), asyncBody (a Parse Node), and asyncContext (an execution context) and returns unused. It performs the following steps when called:

  1. Assert: promiseCapability is a PromiseCapability Record.
  2. Let runningContext be the running execution context.
  3. Let closure be a new Abstract Closure with no parameters that captures promiseCapability and asyncBody and performs the following steps when called:
    1. Let acAsyncContext be the running execution context.
    2. Let result be Completion(Evaluation of asyncBody).
    3. Assert: If we return here, the async function either threw an exception or performed an implicit or explicit return; all awaiting is done.
    4. Remove acAsyncContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
    5. If result is a normal completion, then
      1. Perform ! Call(promiseCapability.[[Resolve]], undefined, « undefined »).
    6. Else if result is a return completion, then
      1. Perform ! Call(promiseCapability.[[Resolve]], undefined, « result.[[Value]] »).
    7. Else,
      1. Assert: result is a throw completion.
      2. Perform ! Call(promiseCapability.[[Reject]], undefined, « result.[[Value]] »).
    8. Return unused.
  4. Set the code evaluation state of asyncContext such that when evaluation is resumed for that execution context, closure will be called with no arguments.
  5. Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
  6. Resume the suspended evaluation of asyncContext. Let result be the value returned by the resumed computation.
  7. Assert: When we return here, asyncContext has already been removed from the execution context stack and runningContext is the currently running execution context.
  8. Assert: result is a normal completion with a value of unused. The possible sources of this value are Await or, if the async function doesn't await anything, step 3.h above.
  9. Return unused.

27.7.5.3 Await ( value )

The abstract operation Await takes argument value (an ECMAScript language value) and returns either a normal completion containing either an ECMAScript language value or empty, or a throw completion. It performs the following steps when called:

  1. Let asyncContext be the running execution context.
  2. Let promise be ? PromiseResolve(%Promise%, value).
  3. Let fulfilledClosure be a new Abstract Closure with parameters (v) that captures asyncContext and performs the following steps when called:
    1. Let prevContext be the running execution context.
    2. Suspend prevContext.
    3. Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
    4. Resume the suspended evaluation of asyncContext using NormalCompletion(v) as the result of the operation that suspended it.
    5. Assert: When we reach this step, asyncContext has already been removed from the execution context stack and prevContext is the currently running execution context.
    6. Return undefined.
  4. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
  5. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures asyncContext and performs the following steps when called:
    1. Let prevContext be the running execution context.
    2. Suspend prevContext.
    3. Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
    4. Resume the suspended evaluation of asyncContext using ThrowCompletion(reason) as the result of the operation that suspended it.
    5. Assert: When we reach this step, asyncContext has already been removed from the execution context stack and prevContext is the currently running execution context.
    6. Return undefined.
  6. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
  7. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
  8. Remove asyncContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
  9. Let callerContext be the running execution context.
  10. Resume callerContext passing empty. If asyncContext is ever resumed again, let completion be the Completion Record with which it is resumed.
  11. Assert: If control reaches here, then asyncContext is the running execution context again.
  12. Return completion.

28 Reflection

28.1 The Reflect Object

The Reflect object:

  • is %Reflect%.
  • is the initial value of the "Reflect" property of the global object.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is not a function object.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • does not have a [[Call]] internal method; it cannot be invoked as a function.

28.1.1 Reflect.apply ( target, thisArgument, argumentsList )

This function performs the following steps when called:

  1. If IsCallable(target) is false, throw a TypeError exception.
  2. Let args be ? CreateListFromArrayLike(argumentsList).
  3. Perform PrepareForTailCall().
  4. Return ? Call(target, thisArgument, args).

28.1.2 Reflect.construct ( target, argumentsList [ , newTarget ] )

This function performs the following steps when called:

  1. If IsConstructor(target) is false, throw a TypeError exception.
  2. If newTarget is not present, set newTarget to target.
  3. Else if IsConstructor(newTarget) is false, throw a TypeError exception.
  4. Let args be ? CreateListFromArrayLike(argumentsList).
  5. Return ? Construct(target, args, newTarget).

28.1.3 Reflect.defineProperty ( target, propertyKey, attributes )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Let desc be ? ToPropertyDescriptor(attributes).
  4. Return ? target.[[DefineOwnProperty]](key, desc).

28.1.4 Reflect.deleteProperty ( target, propertyKey )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Return ? target.[[Delete]](key).

28.1.5 Reflect.get ( target, propertyKey [ , receiver ] )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. If receiver is not present, then
    1. Set receiver to target.
  4. Return ? target.[[Get]](key, receiver).

28.1.6 Reflect.getOwnPropertyDescriptor ( target, propertyKey )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Let desc be ? target.[[GetOwnProperty]](key).
  4. Return FromPropertyDescriptor(desc).

28.1.7 Reflect.getPrototypeOf ( target )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Return ? target.[[GetPrototypeOf]]().

28.1.8 Reflect.has ( target, propertyKey )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Return ? target.[[HasProperty]](key).

28.1.9 Reflect.isExtensible ( target )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Return ? target.[[IsExtensible]]().

28.1.10 Reflect.ownKeys ( target )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let keys be ? target.[[OwnPropertyKeys]]().
  3. Return CreateArrayFromList(keys).

28.1.11 Reflect.preventExtensions ( target )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Return ? target.[[PreventExtensions]]().

28.1.12 Reflect.set ( target, propertyKey, V [ , receiver ] )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. If receiver is not present, then
    1. Set receiver to target.
  4. Return ? target.[[Set]](key, V, receiver).

28.1.13 Reflect.setPrototypeOf ( target, proto )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. If proto is not an Object and proto is not null, throw a TypeError exception.
  3. Return ? target.[[SetPrototypeOf]](proto).

28.1.14 Reflect [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Reflect".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

28.2 Proxy Objects

28.2.1 The Proxy Constructor

The Proxy constructor:

  • is %Proxy%.
  • is the initial value of the "Proxy" property of the global object.
  • creates and initializes a new Proxy object when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.

28.2.1.1 Proxy ( target, handler )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Return ? ProxyCreate(target, handler).

28.2.2 Properties of the Proxy Constructor

The Proxy constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • does not have a "prototype" property because Proxy objects do not have a [[Prototype]] internal slot that requires initialization.
  • has the following properties:

28.2.2.1 Proxy.revocable ( target, handler )

This function creates a revocable Proxy object.

It performs the following steps when called:

  1. Let proxy be ? ProxyCreate(target, handler).
  2. Let revokerClosure be a new Abstract Closure with no parameters that captures nothing and performs the following steps when called:
    1. Let F be the active function object.
    2. Let p be F.[[RevocableProxy]].
    3. If p is null, return undefined.
    4. Set F.[[RevocableProxy]] to null.
    5. Assert: p is a Proxy exotic object.
    6. Set p.[[ProxyTarget]] to null.
    7. Set p.[[ProxyHandler]] to null.
    8. Return undefined.
  3. Let revoker be CreateBuiltinFunction(revokerClosure, 0, "", « [[RevocableProxy]] »).
  4. Set revoker.[[RevocableProxy]] to proxy.
  5. Let result be OrdinaryObjectCreate(%Object.prototype%).
  6. Perform ! CreateDataPropertyOrThrow(result, "proxy", proxy).
  7. Perform ! CreateDataPropertyOrThrow(result, "revoke", revoker).
  8. Return result.

28.3 Module Namespace Objects

A Module Namespace Object is a module namespace exotic object that provides runtime property-based access to a module's exported bindings. There is no constructor function for Module Namespace Objects. Instead, such an object is created for each module that is imported by an ImportDeclaration that contains a NameSpaceImport.

In addition to the properties specified in 10.4.6 each Module Namespace Object has the following own property:

28.3.1 @@toStringTag

The initial value of the @@toStringTag property is the String value "Module".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

29 Memory Model

The memory consistency model, or memory model, specifies the possible orderings of Shared Data Block events, arising via accessing TypedArray instances backed by a SharedArrayBuffer and via methods on the Atomics object. When the program has no data races (defined below), the ordering of events appears as sequentially consistent, i.e., as an interleaving of actions from each agent. When the program has data races, shared memory operations may appear sequentially inconsistent. For example, programs may exhibit causality-violating behaviour and other astonishments. These astonishments arise from compiler transforms and the design of CPUs (e.g., out-of-order execution and speculation). The memory model defines both the precise conditions under which a program exhibits sequentially consistent behaviour as well as the possible values read from data races. To wit, there is no undefined behaviour.

The memory model is defined as relational constraints on events introduced by abstract operations on SharedArrayBuffer or by methods on the Atomics object during an evaluation.

Note

This section provides an axiomatic model on events introduced by the abstract operations on SharedArrayBuffers. It bears stressing that the model is not expressible algorithmically, unlike the rest of this specification. The nondeterministic introduction of events by abstract operations is the interface between the operational semantics of ECMAScript evaluation and the axiomatic semantics of the memory model. The semantics of these events is defined by considering graphs of all events in an evaluation. These are neither Static Semantics nor Runtime Semantics. There is no demonstrated algorithmic implementation, but instead a set of constraints that determine if a particular event graph is allowed or disallowed.

29.1 Memory Model Fundamentals

Shared memory accesses (reads and writes) are divided into two groups, atomic accesses and data accesses, defined below. Atomic accesses are sequentially consistent, i.e., there is a strict total ordering of events agreed upon by all agents in an agent cluster. Non-atomic accesses do not have a strict total ordering agreed upon by all agents, i.e., unordered.

Note 1

No orderings weaker than sequentially consistent and stronger than unordered, such as release-acquire, are supported.

A Shared Data Block event is either a ReadSharedMemory, WriteSharedMemory, or ReadModifyWriteSharedMemory Record.

Table 91: ReadSharedMemory Event Fields
Field Name Value Meaning
[[Order]] seq-cst or unordered The weakest ordering guaranteed by the memory model for the event.
[[NoTear]] a Boolean Whether this event is allowed to read from multiple write events with equal range as this event.
[[Block]] a Shared Data Block The block the event operates on.
[[ByteIndex]] a non-negative integer The byte address of the read in [[Block]].
[[ElementSize]] a non-negative integer The size of the read.
Table 92: WriteSharedMemory Event Fields
Field Name Value Meaning
[[Order]] seq-cst, unordered, or init The weakest ordering guaranteed by the memory model for the event.
[[NoTear]] a Boolean Whether this event is allowed to be read from multiple read events with equal range as this event.
[[Block]] a Shared Data Block The block the event operates on.
[[ByteIndex]] a non-negative integer The byte address of the write in [[Block]].
[[ElementSize]] a non-negative integer The size of the write.
[[Payload]] a List of byte values The List of byte values to be read by other events.
Table 93: ReadModifyWriteSharedMemory Event Fields
Field Name Value Meaning
[[Order]] seq-cst Read-modify-write events are always sequentially consistent.
[[NoTear]] true Read-modify-write events cannot tear.
[[Block]] a Shared Data Block The block the event operates on.
[[ByteIndex]] a non-negative integer The byte address of the read-modify-write in [[Block]].
[[ElementSize]] a non-negative integer The size of the read-modify-write.
[[Payload]] a List of byte values The List of byte values to be passed to [[ModifyOp]].
[[ModifyOp]] a read-modify-write modification function An abstract closure that returns a modified List of byte values from a read List of byte values and [[Payload]].

These events are introduced by abstract operations or by methods on the Atomics object.

Some operations may also introduce Synchronize events. A Synchronize event has no fields, and exists purely to directly constrain the permitted orderings of other events.

In addition to Shared Data Block and Synchronize events, there are host-specific events.

Let the range of a ReadSharedMemory, WriteSharedMemory, or ReadModifyWriteSharedMemory event be the Set of contiguous integers from its [[ByteIndex]] to [[ByteIndex]] + [[ElementSize]] - 1. Two events' ranges are equal when the events have the same [[Block]], and the ranges are element-wise equal. Two events' ranges are overlapping when the events have the same [[Block]], the ranges are not equal and their intersection is non-empty. Two events' ranges are disjoint when the events do not have the same [[Block]] or their ranges are neither equal nor overlapping.

Note 2

Examples of host-specific synchronizing events that should be accounted for are: sending a SharedArrayBuffer from one agent to another (e.g., by postMessage in a browser), starting and stopping agents, and communicating within the agent cluster via channels other than shared memory. It is assumed those events are appended to agent-order during evaluation like the other SharedArrayBuffer events.

Events are ordered within candidate executions by the relations defined below.

29.2 Agent Events Records

An Agent Events Record is a Record with the following fields.

Table 94: Agent Events Record Fields
Field Name Value Meaning
[[AgentSignifier]] an agent signifier The agent whose evaluation resulted in this ordering.
[[EventList]] a List of events Events are appended to the list during evaluation.
[[AgentSynchronizesWith]] a List of pairs of Synchronize events Synchronize relationships introduced by the operational semantics.

29.3 Chosen Value Records

A Chosen Value Record is a Record with the following fields.

Table 95: Chosen Value Record Fields
Field Name Value Meaning
[[Event]] a Shared Data Block event The ReadSharedMemory or ReadModifyWriteSharedMemory event that was introduced for this chosen value.
[[ChosenValue]] a List of byte values The bytes that were nondeterministically chosen during evaluation.

29.4 Candidate Executions

A candidate execution of the evaluation of an agent cluster is a Record with the following fields.

Table 96: Candidate Execution Record Fields
Field Name Value Meaning
[[EventsRecords]] a List of Agent Events Records Maps an agent to Lists of events appended during the evaluation.
[[ChosenValues]] a List of Chosen Value Records Maps ReadSharedMemory or ReadModifyWriteSharedMemory events to the List of byte values chosen during the evaluation.
[[AgentOrder]] an agent-order Relation Defined below.
[[ReadsBytesFrom]] a reads-bytes-from mathematical function Defined below.
[[ReadsFrom]] a reads-from Relation Defined below.
[[HostSynchronizesWith]] a host-synchronizes-with Relation Defined below.
[[SynchronizesWith]] a synchronizes-with Relation Defined below.
[[HappensBefore]] a happens-before Relation Defined below.

An empty candidate execution is a candidate execution Record whose fields are empty Lists and Relations.

29.5 Abstract Operations for the Memory Model

29.5.1 EventSet ( execution )

The abstract operation EventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. Let events be an empty Set.
  2. For each Agent Events Record aer of execution.[[EventsRecords]], do
    1. For each event E of aer.[[EventList]], do
      1. Add E to events.
  3. Return events.

29.5.2 SharedDataBlockEventSet ( execution )

The abstract operation SharedDataBlockEventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. Let events be an empty Set.
  2. For each event E of EventSet(execution), do
    1. If E is a ReadSharedMemory, WriteSharedMemory, or ReadModifyWriteSharedMemory event, add E to events.
  3. Return events.

29.5.3 HostEventSet ( execution )

The abstract operation HostEventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. Let events be an empty Set.
  2. For each event E of EventSet(execution), do
    1. If E is not in SharedDataBlockEventSet(execution), add E to events.
  3. Return events.

29.5.4 ComposeWriteEventBytes ( execution, byteIndex, Ws )

The abstract operation ComposeWriteEventBytes takes arguments execution (a candidate execution), byteIndex (a non-negative integer), and Ws (a List of either WriteSharedMemory or ReadModifyWriteSharedMemory events) and returns a List of byte values. It performs the following steps when called:

  1. Let byteLocation be byteIndex.
  2. Let bytesRead be a new empty List.
  3. For each element W of Ws, do
    1. Assert: W has byteLocation in its range.
    2. Let payloadIndex be byteLocation - W.[[ByteIndex]].
    3. If W is a WriteSharedMemory event, then
      1. Let byte be W.[[Payload]][payloadIndex].
    4. Else,
      1. Assert: W is a ReadModifyWriteSharedMemory event.
      2. Let bytes be ValueOfReadEvent(execution, W).
      3. Let bytesModified be W.[[ModifyOp]](bytes, W.[[Payload]]).
      4. Let byte be bytesModified[payloadIndex].
    5. Append byte to bytesRead.
    6. Set byteLocation to byteLocation + 1.
  4. Return bytesRead.
Note 1

The read-modify-write modification [[ModifyOp]] is given by the function properties on the Atomics object that introduce ReadModifyWriteSharedMemory events.

Note 2

This abstract operation composes a List of write events into a List of byte values. It is used in the event semantics of ReadSharedMemory and ReadModifyWriteSharedMemory events.

29.5.5 ValueOfReadEvent ( execution, R )

The abstract operation ValueOfReadEvent takes arguments execution (a candidate execution) and R (a ReadSharedMemory or ReadModifyWriteSharedMemory event) and returns a List of byte values. It performs the following steps when called:

  1. Let Ws be execution.[[ReadsBytesFrom]](R).
  2. Assert: Ws is a List of WriteSharedMemory or ReadModifyWriteSharedMemory events with length equal to R.[[ElementSize]].
  3. Return ComposeWriteEventBytes(execution, R.[[ByteIndex]], Ws).

29.6 Relations of Candidate Executions

29.6.1 agent-order

For a candidate execution execution, execution.[[AgentOrder]] is a Relation on events that satisfies the following.

  • For each pair (E, D) in EventSet(execution), execution.[[AgentOrder]] contains (E, D) if there is some Agent Events Record aer in execution.[[EventsRecords]] such that E and D are in aer.[[EventList]] and E is before D in List order of aer.[[EventList]].
Note

Each agent introduces events in a per-agent strict total order during the evaluation. This is the union of those strict total orders.

29.6.2 reads-bytes-from

For a candidate execution execution, execution.[[ReadsBytesFrom]] is a mathematical function mapping events in SharedDataBlockEventSet(execution) to Lists of events in SharedDataBlockEventSet(execution) that satisfies the following conditions.

29.6.3 reads-from

For a candidate execution execution, execution.[[ReadsFrom]] is the least Relation on events that satisfies the following.

  • For each pair (R, W) in SharedDataBlockEventSet(execution), execution.[[ReadsFrom]] contains (R, W) if execution.[[ReadsBytesFrom]](R) contains W.

29.6.4 host-synchronizes-with

For a candidate execution execution, execution.[[HostSynchronizesWith]] is a host-provided strict partial order on host-specific events that satisfies at least the following.

  • If execution.[[HostSynchronizesWith]] contains (E, D), E and D are in HostEventSet(execution).
  • There is no cycle in the union of execution.[[HostSynchronizesWith]] and execution.[[AgentOrder]].
Note 1

For two host-specific events E and D, E host-synchronizes-with D implies E happens-before D.

Note 2

The host-synchronizes-with relation allows the host to provide additional synchronization mechanisms, such as postMessage between HTML workers.

29.6.5 synchronizes-with

For a candidate execution execution, execution.[[SynchronizesWith]] is the least Relation on events that satisfies the following.

  • For each pair (R, W) in execution.[[ReadsFrom]], execution.[[SynchronizesWith]] contains (W, R) if R.[[Order]] is seq-cst, W.[[Order]] is seq-cst, and R and W have equal ranges.
  • For each element eventsRecord of execution.[[EventsRecords]], the following is true.
    • For each pair (S, Sw) in eventsRecord.[[AgentSynchronizesWith]], execution.[[SynchronizesWith]] contains (S, Sw).
  • For each pair (E, D) in execution.[[HostSynchronizesWith]], execution.[[SynchronizesWith]] contains (E, D).
Note 1

Owing to convention, write events synchronizes-with read events, instead of read events synchronizes-with write events.

Note 2

init events do not participate in synchronizes-with, and are instead constrained directly by happens-before.

Note 3

Not all seq-cst events related by reads-from are related by synchronizes-with. Only events that also have equal ranges are related by synchronizes-with.

Note 4

For Shared Data Block events R and W such that W synchronizes-with R, R may reads-from other writes than W.

29.6.6 happens-before

For a candidate execution execution, execution.[[HappensBefore]] is the least Relation on events that satisfies the following.

  • For each pair (E, D) in execution.[[AgentOrder]], execution.[[HappensBefore]] contains (E, D).
  • For each pair (E, D) in execution.[[SynchronizesWith]], execution.[[HappensBefore]] contains (E, D).
  • For each pair (E, D) in SharedDataBlockEventSet(execution), execution.[[HappensBefore]] contains (E, D) if E.[[Order]] is init and E and D have overlapping ranges.
  • For each pair (E, D) in EventSet(execution), execution.[[HappensBefore]] contains (E, D) if there is an event F such that the pairs (E, F) and (F, D) are in execution.[[HappensBefore]].
Note

Because happens-before is a superset of agent-order, candidate executions are consistent with the single-thread evaluation semantics of ECMAScript.

29.7 Properties of Valid Executions

29.7.1 Valid Chosen Reads

A candidate execution execution has valid chosen reads if the following algorithm returns true.

  1. For each ReadSharedMemory or ReadModifyWriteSharedMemory event R of SharedDataBlockEventSet(execution), do
    1. Let chosenValueRecord be the element of execution.[[ChosenValues]] whose [[Event]] field is R.
    2. Let chosenValue be chosenValueRecord.[[ChosenValue]].
    3. Let readValue be ValueOfReadEvent(execution, R).
    4. Let chosenLen be the number of elements in chosenValue.
    5. Let readLen be the number of elements in readValue.
    6. If chosenLenreadLen, then
      1. Return false.
    7. If chosenValue[i] ≠ readValue[i] for some integer i in the interval from 0 (inclusive) to chosenLen (exclusive), then
      1. Return false.
  2. Return true.

29.7.2 Coherent Reads

A candidate execution execution has coherent reads if the following algorithm returns true.

  1. For each ReadSharedMemory or ReadModifyWriteSharedMemory event R of SharedDataBlockEventSet(execution), do
    1. Let Ws be execution.[[ReadsBytesFrom]](R).
    2. Let byteLocation be R.[[ByteIndex]].
    3. For each element W of Ws, do
      1. If execution.[[HappensBefore]] contains (R, W), then
        1. Return false.
      2. If there exists a WriteSharedMemory or ReadModifyWriteSharedMemory event V that has byteLocation in its range such that the pairs (W, V) and (V, R) are in execution.[[HappensBefore]], then
        1. Return false.
      3. Set byteLocation to byteLocation + 1.
  2. Return true.

29.7.3 Tear Free Reads

A candidate execution execution has tear free reads if the following algorithm returns true.

  1. For each ReadSharedMemory or ReadModifyWriteSharedMemory event R of SharedDataBlockEventSet(execution), do
    1. If R.[[NoTear]] is true, then
      1. Assert: The remainder of dividing R.[[ByteIndex]] by R.[[ElementSize]] is 0.
      2. For each event W such that execution.[[ReadsFrom]] contains (R, W) and W.[[NoTear]] is true, do
        1. If R and W have equal ranges and there exists an event V such that V and W have equal ranges, V.[[NoTear]] is true, W is not V, and execution.[[ReadsFrom]] contains (R, V), then
          1. Return false.
  2. Return true.
Note

An event's [[NoTear]] field is true when that event was introduced via accessing an integer TypedArray, and false when introduced via accessing a floating point TypedArray or DataView.

Intuitively, this requirement says when a memory range is accessed in an aligned fashion via an integer TypedArray, a single write event on that range must "win" when in a data race with other write events with equal ranges. More precisely, this requirement says an aligned read event cannot read a value composed of bytes from multiple, different write events all with equal ranges. It is possible, however, for an aligned read event to read from multiple write events with overlapping ranges.

29.7.4 Sequentially Consistent Atomics

For a candidate execution execution, memory-order is a strict total order of all events in EventSet(execution) that satisfies the following.

  • For each pair (E, D) in execution.[[HappensBefore]], (E, D) is in memory-order.
  • For each pair (R, W) in execution.[[ReadsFrom]], there is no WriteSharedMemory or ReadModifyWriteSharedMemory event V in SharedDataBlockEventSet(execution) such that V.[[Order]] is seq-cst, the pairs (W, V) and (V, R) are in memory-order, and any of the following conditions are true.

    • execution.[[SynchronizesWith]] contains the pair (W, R), and V and R have equal ranges.
    • The pairs (W, R) and (V, R) are in execution.[[HappensBefore]], W.[[Order]] is seq-cst, and W and V have equal ranges.
    • The pairs (W, R) and (W, V) are in execution.[[HappensBefore]], R.[[Order]] is seq-cst, and V and R have equal ranges.
    Note 1

    This clause additionally constrains seq-cst events on equal ranges.

  • For each WriteSharedMemory or ReadModifyWriteSharedMemory event W in SharedDataBlockEventSet(execution), if W.[[Order]] is seq-cst, then it is not the case that there is an infinite number of ReadSharedMemory or ReadModifyWriteSharedMemory events in SharedDataBlockEventSet(execution) with equal range that is memory-order before W.

    Note 2

    This clause together with the forward progress guarantee on agents ensure the liveness condition that seq-cst writes become visible to seq-cst reads with equal range in finite time.

A candidate execution has sequentially consistent atomics if a memory-order exists.

Note 3

While memory-order includes all events in EventSet(execution), those that are not constrained by happens-before or synchronizes-with are allowed to occur anywhere in the order.

29.7.5 Valid Executions

A candidate execution execution is a valid execution (or simply an execution) if all of the following are true.

  • The host provides a host-synchronizes-with Relation for execution.[[HostSynchronizesWith]].
  • execution.[[HappensBefore]] is a strict partial order.
  • execution has valid chosen reads.
  • execution has coherent reads.
  • execution has tear free reads.
  • execution has sequentially consistent atomics.

All programs have at least one valid execution.

29.8 Races

For an execution execution, two events E and D in SharedDataBlockEventSet(execution) are in a race if the following algorithm returns true.

  1. If E is not D, then
    1. If the pairs (E, D) and (D, E) are not in execution.[[HappensBefore]], then
      1. If E and D are both WriteSharedMemory or ReadModifyWriteSharedMemory events and E and D do not have disjoint ranges, then
        1. Return true.
      2. If execution.[[ReadsFrom]] contains either (E, D) or (D, E), then
        1. Return true.
  2. Return false.

29.9 Data Races

For an execution execution, two events E and D in SharedDataBlockEventSet(execution) are in a data race if the following algorithm returns true.

  1. If E and D are in a race in execution, then
    1. If E.[[Order]] is not seq-cst or D.[[Order]] is not seq-cst, then
      1. Return true.
    2. If E and D have overlapping ranges, then
      1. Return true.
  2. Return false.

29.10 Data Race Freedom

An execution execution is data race free if there are no two events in SharedDataBlockEventSet(execution) that are in a data race.

A program is data race free if all its executions are data race free.

The memory model guarantees sequential consistency of all events for data race free programs.

29.11 Shared Memory Guidelines

Note 1

The following are guidelines for ECMAScript programmers working with shared memory.

We recommend programs be kept data race free, i.e., make it so that it is impossible for there to be concurrent non-atomic operations on the same memory location. Data race free programs have interleaving semantics where each step in the evaluation semantics of each agent are interleaved with each other. For data race free programs, it is not necessary to understand the details of the memory model. The details are unlikely to build intuition that will help one to better write ECMAScript.

More generally, even if a program is not data race free it may have predictable behaviour, so long as atomic operations are not involved in any data races and the operations that race all have the same access size. The simplest way to arrange for atomics not to be involved in races is to ensure that different memory cells are used by atomic and non-atomic operations and that atomic accesses of different sizes are not used to access the same cells at the same time. Effectively, the program should treat shared memory as strongly typed as much as possible. One still cannot depend on the ordering and timing of non-atomic accesses that race, but if memory is treated as strongly typed the racing accesses will not "tear" (bits of their values will not be mixed).

Note 2

The following are guidelines for ECMAScript implementers writing compiler transformations for programs using shared memory.

It is desirable to allow most program transformations that are valid in a single-agent setting in a multi-agent setting, to ensure that the performance of each agent in a multi-agent program is as good as it would be in a single-agent setting. Frequently these transformations are hard to judge. We outline some rules about program transformations that are intended to be taken as normative (in that they are implied by the memory model or stronger than what the memory model implies) but which are likely not exhaustive. These rules are intended to apply to program transformations that precede the introductions of the events that make up the agent-order.

Let an agent-order slice be the subset of the agent-order pertaining to a single agent.

Let possible read values of a read event be the set of all values of ValueOfReadEvent for that event across all valid executions.

Any transformation of an agent-order slice that is valid in the absence of shared memory is valid in the presence of shared memory, with the following exceptions.

  • Atomics are carved in stone: Program transformations must not cause the seq-cst events in an agent-order slice to be reordered with its unordered operations, nor its seq-cst operations to be reordered with each other, nor may a program transformation remove a seq-cst operation from the agent-order.

    (In practice, the prohibition on reorderings forces a compiler to assume that every seq-cst operation is a synchronization and included in the final memory-order, which it would usually have to assume anyway in the absence of inter-agent program analysis. It also forces the compiler to assume that every call where the callee's effects on the memory-order are unknown may contain seq-cst operations.)

  • Reads must be stable: Any given shared memory read must only observe a single value in an execution.

    (For example, if what is semantically a single read in the program is executed multiple times then the program is subsequently allowed to observe only one of the values read. A transformation known as rematerialization can violate this rule.)

  • Writes must be stable: All observable writes to shared memory must follow from program semantics in an execution.

    (For example, a transformation may not introduce certain observable writes, such as by using read-modify-write operations on a larger location to write a smaller datum, writing a value to memory that the program could not have written, or writing a just-read value back to the location it was read from, if that location could have been overwritten by another agent after the read.)

  • Possible read values must be non-empty: Program transformations cannot cause the possible read values of a shared memory read to become empty.

    (Counterintuitively, this rule in effect restricts transformations on writes, because writes have force in memory model insofar as to be read by read events. For example, writes may be moved and coalesced and sometimes reordered between two seq-cst operations, but the transformation may not remove every write that updates a location; some write must be preserved.)

Examples of transformations that remain valid are: merging multiple non-atomic reads from the same location, reordering non-atomic reads, introducing speculative non-atomic reads, merging multiple non-atomic writes to the same location, reordering non-atomic writes to different locations, and hoisting non-atomic reads out of loops even if that affects termination. Note in general that aliased TypedArrays make it hard to prove that locations are different.

Note 3

The following are guidelines for ECMAScript implementers generating machine code for shared memory accesses.

For architectures with memory models no weaker than those of ARM or Power, non-atomic stores and loads may be compiled to bare stores and loads on the target architecture. Atomic stores and loads may be compiled down to instructions that guarantee sequential consistency. If no such instructions exist, memory barriers are to be employed, such as placing barriers on both sides of a bare store or load. Read-modify-write operations may be compiled to read-modify-write instructions on the target architecture, such as LOCK-prefixed instructions on x86, load-exclusive/store-exclusive instructions on ARM, and load-link/store-conditional instructions on Power.

Specifically, the memory model is intended to allow code generation as follows.

  • Every atomic operation in the program is assumed to be necessary.
  • Atomic operations are never rearranged with each other or with non-atomic operations.
  • Functions are always assumed to perform atomic operations.
  • Atomic operations are never implemented as read-modify-write operations on larger data, but as non-lock-free atomics if the platform does not have atomic operations of the appropriate size. (We already assume that every platform has normal memory access operations of every interesting size.)

Naive code generation uses these patterns:

  • Regular loads and stores compile to single load and store instructions.
  • Lock-free atomic loads and stores compile to a full (sequentially consistent) fence, a regular load or store, and a full fence.
  • Lock-free atomic read-modify-write accesses compile to a full fence, an atomic read-modify-write instruction sequence, and a full fence.
  • Non-lock-free atomics compile to a spinlock acquire, a full fence, a series of non-atomic load and store instructions, a full fence, and a spinlock release.

That mapping is correct so long as an atomic operation on an address range does not race with a non-atomic write or with an atomic operation of different size. However, that is all we need: the memory model effectively demotes the atomic operations involved in a race to non-atomic status. On the other hand, the naive mapping is quite strong: it allows atomic operations to be used as sequentially consistent fences, which the memory model does not actually guarantee.

Local improvements to those basic patterns are also allowed, subject to the constraints of the memory model. For example:

  • There are obvious platform-dependent improvements that remove redundant fences. For example, on x86 the fences around lock-free atomic loads and stores can always be omitted except for the fence following a store, and no fence is needed for lock-free read-modify-write instructions, as these all use LOCK-prefixed instructions. On many platforms there are fences of several strengths, and weaker fences can be used in certain contexts without destroying sequential consistency.
  • Most modern platforms support lock-free atomics for all the data sizes required by ECMAScript atomics. Should non-lock-free atomics be needed, the fences surrounding the body of the atomic operation can usually be folded into the lock and unlock steps. The simplest solution for non-lock-free atomics is to have a single lock word per SharedArrayBuffer.
  • There are also more complicated platform-dependent local improvements, requiring some code analysis. For example, two back-to-back fences often have the same effect as a single fence, so if code is generated for two atomic operations in sequence, only a single fence need separate them. On x86, even a single fence separating atomic stores can be omitted, as the fence following a store is only needed to separate the store from a subsequent load.

A Grammar Summary

A.1 Lexical Grammar

SourceCharacter :: any Unicode code point InputElementDiv :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator RightBracePunctuator InputElementRegExp :: WhiteSpace LineTerminator Comment CommonToken RightBracePunctuator RegularExpressionLiteral InputElementRegExpOrTemplateTail :: WhiteSpace LineTerminator Comment CommonToken RegularExpressionLiteral TemplateSubstitutionTail InputElementTemplateTail :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator TemplateSubstitutionTail InputElementHashbangOrRegExp :: WhiteSpace LineTerminator Comment CommonToken HashbangComment RegularExpressionLiteral WhiteSpace :: <TAB> <VT> <FF> <ZWNBSP> <USP> LineTerminator :: <LF> <CR> <LS> <PS> LineTerminatorSequence :: <LF> <CR> [lookahead ≠ <LF>] <LS> <PS> <CR> <LF> Comment :: MultiLineComment SingleLineComment MultiLineComment :: /* MultiLineCommentCharsopt */ MultiLineCommentChars :: MultiLineNotAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt PostAsteriskCommentChars :: MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt MultiLineNotAsteriskChar :: SourceCharacter but not * MultiLineNotForwardSlashOrAsteriskChar :: SourceCharacter but not one of / or * SingleLineComment :: // SingleLineCommentCharsopt SingleLineCommentChars :: SingleLineCommentChar SingleLineCommentCharsopt SingleLineCommentChar :: SourceCharacter but not LineTerminator HashbangComment :: #! SingleLineCommentCharsopt CommonToken :: IdentifierName PrivateIdentifier Punctuator NumericLiteral StringLiteral Template PrivateIdentifier :: # IdentifierName IdentifierName :: IdentifierStart IdentifierName IdentifierPart IdentifierStart :: IdentifierStartChar \ UnicodeEscapeSequence IdentifierPart :: IdentifierPartChar \ UnicodeEscapeSequence IdentifierStartChar :: UnicodeIDStart $ _ IdentifierPartChar :: UnicodeIDContinue $ <ZWNJ> <ZWJ> AsciiLetter :: one of a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z UnicodeIDStart :: any Unicode code point with the Unicode property “ID_Start” UnicodeIDContinue :: any Unicode code point with the Unicode property “ID_Continue” ReservedWord :: one of await break case catch class const continue debugger default delete do else enum export extends false finally for function if import in instanceof new null return super switch this throw true try typeof var void while with yield Punctuator :: OptionalChainingPunctuator OtherPunctuator OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit] OtherPunctuator :: one of { ( ) [ ] . ... ; , < > <= >= == != === !== + - * % ** ++ -- << >> >>> & | ^ ! ~ && || ?? ? : = += -= *= %= **= <<= >>= >>>= &= |= ^= &&= ||= ??= => DivPunctuator :: / /= RightBracePunctuator :: } NullLiteral :: null BooleanLiteral :: true false NumericLiteralSeparator :: _ NumericLiteral :: DecimalLiteral DecimalBigIntegerLiteral NonDecimalIntegerLiteral[+Sep] NonDecimalIntegerLiteral[+Sep] BigIntLiteralSuffix LegacyOctalIntegerLiteral DecimalBigIntegerLiteral :: 0 BigIntLiteralSuffix NonZeroDigit DecimalDigits[+Sep]opt BigIntLiteralSuffix NonZeroDigit NumericLiteralSeparator DecimalDigits[+Sep] BigIntLiteralSuffix NonDecimalIntegerLiteral[Sep] :: BinaryIntegerLiteral[?Sep] OctalIntegerLiteral[?Sep] HexIntegerLiteral[?Sep] BigIntLiteralSuffix :: n DecimalLiteral :: DecimalIntegerLiteral . DecimalDigits[+Sep]opt ExponentPart[+Sep]opt . DecimalDigits[+Sep] ExponentPart[+Sep]opt DecimalIntegerLiteral ExponentPart[+Sep]opt DecimalIntegerLiteral :: 0 NonZeroDigit NonZeroDigit NumericLiteralSeparatoropt DecimalDigits[+Sep] NonOctalDecimalIntegerLiteral DecimalDigits[Sep] :: DecimalDigit DecimalDigits[?Sep] DecimalDigit [+Sep] DecimalDigits[+Sep] NumericLiteralSeparator DecimalDigit DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9 NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9 ExponentPart[Sep] :: ExponentIndicator SignedInteger[?Sep] ExponentIndicator :: one of e E SignedInteger[Sep] :: DecimalDigits[?Sep] + DecimalDigits[?Sep] - DecimalDigits[?Sep] BinaryIntegerLiteral[Sep] :: 0b BinaryDigits[?Sep] 0B BinaryDigits[?Sep] BinaryDigits[Sep] :: BinaryDigit BinaryDigits[?Sep] BinaryDigit [+Sep] BinaryDigits[+Sep] NumericLiteralSeparator BinaryDigit BinaryDigit :: one of 0 1 OctalIntegerLiteral[Sep] :: 0o OctalDigits[?Sep] 0O OctalDigits[?Sep] OctalDigits[Sep] :: OctalDigit OctalDigits[?Sep] OctalDigit [+Sep] OctalDigits[+Sep] NumericLiteralSeparator OctalDigit LegacyOctalIntegerLiteral :: 0 OctalDigit LegacyOctalIntegerLiteral OctalDigit NonOctalDecimalIntegerLiteral :: 0 NonOctalDigit LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit NonOctalDecimalIntegerLiteral DecimalDigit LegacyOctalLikeDecimalIntegerLiteral :: 0 OctalDigit LegacyOctalLikeDecimalIntegerLiteral OctalDigit OctalDigit :: one of 0 1 2 3 4 5 6 7 NonOctalDigit :: one of 8 9 HexIntegerLiteral[Sep] :: 0x HexDigits[?Sep] 0X HexDigits[?Sep] HexDigits[Sep] :: HexDigit HexDigits[?Sep] HexDigit [+Sep] HexDigits[+Sep] NumericLiteralSeparator HexDigit HexDigit :: one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F StringLiteral :: " DoubleStringCharactersopt " ' SingleStringCharactersopt ' DoubleStringCharacters :: DoubleStringCharacter DoubleStringCharactersopt SingleStringCharacters :: SingleStringCharacter SingleStringCharactersopt DoubleStringCharacter :: SourceCharacter but not one of " or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation SingleStringCharacter :: SourceCharacter but not one of ' or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation LineContinuation :: \ LineTerminatorSequence EscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence HexEscapeSequence UnicodeEscapeSequence CharacterEscapeSequence :: SingleEscapeCharacter NonEscapeCharacter SingleEscapeCharacter :: one of ' " \ b f n r t v NonEscapeCharacter :: SourceCharacter but not one of EscapeCharacter or LineTerminator EscapeCharacter :: SingleEscapeCharacter DecimalDigit x u LegacyOctalEscapeSequence :: 0 [lookahead ∈ { 8, 9 }] NonZeroOctalDigit [lookahead ∉ OctalDigit] ZeroToThree OctalDigit [lookahead ∉ OctalDigit] FourToSeven OctalDigit ZeroToThree OctalDigit OctalDigit NonZeroOctalDigit :: OctalDigit but not 0 ZeroToThree :: one of 0 1 2 3 FourToSeven :: one of 4 5 6 7 NonOctalDecimalEscapeSequence :: one of 8 9 HexEscapeSequence :: x HexDigit HexDigit UnicodeEscapeSequence :: u Hex4Digits u{ CodePoint } Hex4Digits :: HexDigit HexDigit HexDigit HexDigit RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags RegularExpressionBody :: RegularExpressionFirstChar RegularExpressionChars RegularExpressionChars :: [empty] RegularExpressionChars RegularExpressionChar RegularExpressionFirstChar :: RegularExpressionNonTerminator but not one of * or \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionChar :: RegularExpressionNonTerminator but not one of \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionBackslashSequence :: \ RegularExpressionNonTerminator RegularExpressionNonTerminator :: SourceCharacter but not LineTerminator RegularExpressionClass :: [ RegularExpressionClassChars ] RegularExpressionClassChars :: [empty] RegularExpressionClassChars RegularExpressionClassChar RegularExpressionClassChar :: RegularExpressionNonTerminator but not one of ] or \ RegularExpressionBackslashSequence RegularExpressionFlags :: [empty] RegularExpressionFlags IdentifierPartChar Template :: NoSubstitutionTemplate TemplateHead NoSubstitutionTemplate :: ` TemplateCharactersopt ` TemplateHead :: ` TemplateCharactersopt ${ TemplateSubstitutionTail :: TemplateMiddle TemplateTail TemplateMiddle :: } TemplateCharactersopt ${ TemplateTail :: } TemplateCharactersopt ` TemplateCharacters :: TemplateCharacter TemplateCharactersopt TemplateCharacter :: $ [lookahead ≠ {] \ TemplateEscapeSequence \ NotEscapeSequence LineContinuation LineTerminatorSequence SourceCharacter but not one of ` or \ or $ or LineTerminator TemplateEscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] HexEscapeSequence UnicodeEscapeSequence NotEscapeSequence :: 0 DecimalDigit DecimalDigit but not 0 x [lookahead ∉ HexDigit] x HexDigit [lookahead ∉ HexDigit] u [lookahead ∉ HexDigit] [lookahead ≠ {] u HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit HexDigit [lookahead ∉ HexDigit] u { [lookahead ∉ HexDigit] u { NotCodePoint [lookahead ∉ HexDigit] u { CodePoint [lookahead ∉ HexDigit] [lookahead ≠ }] NotCodePoint :: HexDigits[~Sep] but only if MV of HexDigits > 0x10FFFF CodePoint :: HexDigits[~Sep] but only if MV of HexDigits ≤ 0x10FFFF

A.2 Expressions

IdentifierReference[Yield, Await] : Identifier [~Yield] yield [~Await] await BindingIdentifier[Yield, Await] : Identifier yield await LabelIdentifier[Yield, Await] : Identifier [~Yield] yield [~Await] await Identifier : IdentifierName but not ReservedWord PrimaryExpression[Yield, Await] : this IdentifierReference[?Yield, ?Await] Literal ArrayLiteral[?Yield, ?Await] ObjectLiteral[?Yield, ?Await] FunctionExpression ClassExpression[?Yield, ?Await] GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral[?Yield, ?Await, ~Tagged] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[Yield, Await] : ( Expression[+In, ?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ) ( ) ( ... BindingIdentifier[?Yield, ?Await] ) ( ... BindingPattern[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingIdentifier[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingPattern[?Yield, ?Await] )

When processing an instance of the production
PrimaryExpression[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
the interpretation of CoverParenthesizedExpressionAndArrowParameterList is refined using the following grammar:

ParenthesizedExpression[Yield, Await] : ( Expression[+In, ?Yield, ?Await] )

 

Literal : NullLiteral BooleanLiteral NumericLiteral StringLiteral ArrayLiteral[Yield, Await] : [ Elisionopt ] [ ElementList[?Yield, ?Await] ] [ ElementList[?Yield, ?Await] , Elisionopt ] ElementList[Yield, Await] : Elisionopt AssignmentExpression[+In, ?Yield, ?Await] Elisionopt SpreadElement[?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt AssignmentExpression[+In, ?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt SpreadElement[?Yield, ?Await] Elision : , Elision , SpreadElement[Yield, Await] : ... AssignmentExpression[+In, ?Yield, ?Await] ObjectLiteral[Yield, Await] : { } { PropertyDefinitionList[?Yield, ?Await] } { PropertyDefinitionList[?Yield, ?Await] , } PropertyDefinitionList[Yield, Await] : PropertyDefinition[?Yield, ?Await] PropertyDefinitionList[?Yield, ?Await] , PropertyDefinition[?Yield, ?Await] PropertyDefinition[Yield, Await] : IdentifierReference[?Yield, ?Await] CoverInitializedName[?Yield, ?Await] PropertyName[?Yield, ?Await] : AssignmentExpression[+In, ?Yield, ?Await] MethodDefinition[?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] PropertyName[Yield, Await] : LiteralPropertyName ComputedPropertyName[?Yield, ?Await] LiteralPropertyName : IdentifierName StringLiteral NumericLiteral ComputedPropertyName[Yield, Await] : [ AssignmentExpression[+In, ?Yield, ?Await] ] CoverInitializedName[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await] Initializer[In, Yield, Await] : = AssignmentExpression[?In, ?Yield, ?Await] TemplateLiteral[Yield, Await, Tagged] : NoSubstitutionTemplate SubstitutionTemplate[?Yield, ?Await, ?Tagged] SubstitutionTemplate[Yield, Await, Tagged] : TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged] TemplateSpans[Yield, Await, Tagged] : TemplateTail TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateTail TemplateMiddleList[Yield, Await, Tagged] : TemplateMiddle Expression[+In, ?Yield, ?Await] TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await] MemberExpression[Yield, Await] : PrimaryExpression[?Yield, ?Await] MemberExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] MemberExpression[?Yield, ?Await] . IdentifierName MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] SuperProperty[?Yield, ?Await] MetaProperty new MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] MemberExpression[?Yield, ?Await] . PrivateIdentifier SuperProperty[Yield, Await] : super [ Expression[+In, ?Yield, ?Await] ] super . IdentifierName MetaProperty : NewTarget ImportMeta NewTarget : new . target ImportMeta : import . meta NewExpression[Yield, Await] : MemberExpression[?Yield, ?Await] new NewExpression[?Yield, ?Await] CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] SuperCall[?Yield, ?Await] ImportCall[?Yield, ?Await] CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await] CallExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] CallExpression[?Yield, ?Await] . IdentifierName CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] CallExpression[?Yield, ?Await] . PrivateIdentifier

When processing an instance of the production
CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await]
the interpretation of CoverCallExpressionAndAsyncArrowHead is refined using the following grammar:

CallMemberExpression[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

 

SuperCall[Yield, Await] : super Arguments[?Yield, ?Await] ImportCall[Yield, Await] : import ( AssignmentExpression[+In, ?Yield, ?Await] ) Arguments[Yield, Await] : ( ) ( ArgumentList[?Yield, ?Await] ) ( ArgumentList[?Yield, ?Await] , ) ArgumentList[Yield, Await] : AssignmentExpression[+In, ?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , ... AssignmentExpression[+In, ?Yield, ?Await] OptionalExpression[Yield, Await] : MemberExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalChain[Yield, Await] : ?. Arguments[?Yield, ?Await] ?. [ Expression[+In, ?Yield, ?Await] ] ?. IdentifierName ?. TemplateLiteral[?Yield, ?Await, +Tagged] ?. PrivateIdentifier OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await] OptionalChain[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] OptionalChain[?Yield, ?Await] . IdentifierName OptionalChain[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] OptionalChain[?Yield, ?Await] . PrivateIdentifier LeftHandSideExpression[Yield, Await] : NewExpression[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalExpression[?Yield, ?Await] UpdateExpression[Yield, Await] : LeftHandSideExpression[?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] ++ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] -- ++ UnaryExpression[?Yield, ?Await] -- UnaryExpression[?Yield, ?Await] UnaryExpression[Yield, Await] : UpdateExpression[?Yield, ?Await] delete UnaryExpression[?Yield, ?Await] void UnaryExpression[?Yield, ?Await] typeof UnaryExpression[?Yield, ?Await] + UnaryExpression[?Yield, ?Await] - UnaryExpression[?Yield, ?Await] ~ UnaryExpression[?Yield, ?Await] ! UnaryExpression[?Yield, ?Await] [+Await] AwaitExpression[?Yield] ExponentiationExpression[Yield, Await] : UnaryExpression[?Yield, ?Await] UpdateExpression[?Yield, ?Await] ** ExponentiationExpression[?Yield, ?Await] MultiplicativeExpression[Yield, Await] : ExponentiationExpression[?Yield, ?Await] MultiplicativeExpression[?Yield, ?Await] MultiplicativeOperator ExponentiationExpression[?Yield, ?Await] MultiplicativeOperator : one of * / % AdditiveExpression[Yield, Await] : MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] + MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] - MultiplicativeExpression[?Yield, ?Await] ShiftExpression[Yield, Await] : AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] << AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >> AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >>> AdditiveExpression[?Yield, ?Await] RelationalExpression[In, Yield, Await] : ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] < ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] > ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] <= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] >= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] instanceof ShiftExpression[?Yield, ?Await] [+In] RelationalExpression[+In, ?Yield, ?Await] in ShiftExpression[?Yield, ?Await] [+In] PrivateIdentifier in ShiftExpression[?Yield, ?Await] EqualityExpression[In, Yield, Await] : RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] == RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] != RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] === RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] !== RelationalExpression[?In, ?Yield, ?Await] BitwiseANDExpression[In, Yield, Await] : EqualityExpression[?In, ?Yield, ?Await] BitwiseANDExpression[?In, ?Yield, ?Await] & EqualityExpression[?In, ?Yield, ?Await] BitwiseXORExpression[In, Yield, Await] : BitwiseANDExpression[?In, ?Yield, ?Await] BitwiseXORExpression[?In, ?Yield, ?Await] ^ BitwiseANDExpression[?In, ?Yield, ?Await] BitwiseORExpression[In, Yield, Await] : BitwiseXORExpression[?In, ?Yield, ?Await] BitwiseORExpression[?In, ?Yield, ?Await] | BitwiseXORExpression[?In, ?Yield, ?Await] LogicalANDExpression[In, Yield, Await] : BitwiseORExpression[?In, ?Yield, ?Await] LogicalANDExpression[?In, ?Yield, ?Await] && BitwiseORExpression[?In, ?Yield, ?Await] LogicalORExpression[In, Yield, Await] : LogicalANDExpression[?In, ?Yield, ?Await] LogicalORExpression[?In, ?Yield, ?Await] || LogicalANDExpression[?In, ?Yield, ?Await] CoalesceExpression[In, Yield, Await] : CoalesceExpressionHead[?In, ?Yield, ?Await] ?? BitwiseORExpression[?In, ?Yield, ?Await] CoalesceExpressionHead[In, Yield, Await] : CoalesceExpression[?In, ?Yield, ?Await] BitwiseORExpression[?In, ?Yield, ?Await] ShortCircuitExpression[In, Yield, Await] : LogicalORExpression[?In, ?Yield, ?Await] CoalesceExpression[?In, ?Yield, ?Await] ConditionalExpression[In, Yield, Await] : ShortCircuitExpression[?In, ?Yield, ?Await] ShortCircuitExpression[?In, ?Yield, ?Await] ? AssignmentExpression[+In, ?Yield, ?Await] : AssignmentExpression[?In, ?Yield, ?Await] AssignmentExpression[In, Yield, Await] : ConditionalExpression[?In, ?Yield, ?Await] [+Yield] YieldExpression[?In, ?Await] ArrowFunction[?In, ?Yield, ?Await] AsyncArrowFunction[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] = AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] AssignmentOperator AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] &&= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ||= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ??= AssignmentExpression[?In, ?Yield, ?Await] AssignmentOperator : one of *= /= %= += -= <<= >>= >>>= &= ^= |= **=

In certain circumstances when processing an instance of the production
AssignmentExpression[In, Yield, Await] : LeftHandSideExpression[?Yield, ?Await] = AssignmentExpression[?In, ?Yield, ?Await]
the interpretation of LeftHandSideExpression is refined using the following grammar:

AssignmentPattern[Yield, Await] : ObjectAssignmentPattern[?Yield, ?Await] ArrayAssignmentPattern[?Yield, ?Await] ObjectAssignmentPattern[Yield, Await] : { } { AssignmentRestProperty[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] , AssignmentRestProperty[?Yield, ?Await]opt } ArrayAssignmentPattern[Yield, Await] : [ Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] [ AssignmentElementList[?Yield, ?Await] ] [ AssignmentElementList[?Yield, ?Await] , Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] AssignmentRestProperty[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] AssignmentPropertyList[Yield, Await] : AssignmentProperty[?Yield, ?Await] AssignmentPropertyList[?Yield, ?Await] , AssignmentProperty[?Yield, ?Await] AssignmentElementList[Yield, Await] : AssignmentElisionElement[?Yield, ?Await] AssignmentElementList[?Yield, ?Await] , AssignmentElisionElement[?Yield, ?Await] AssignmentElisionElement[Yield, Await] : Elisionopt AssignmentElement[?Yield, ?Await] AssignmentProperty[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt PropertyName[?Yield, ?Await] : AssignmentElement[?Yield, ?Await] AssignmentElement[Yield, Await] : DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt AssignmentRestElement[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] DestructuringAssignmentTarget[Yield, Await] : LeftHandSideExpression[?Yield, ?Await]

 

Expression[In, Yield, Await] : AssignmentExpression[?In, ?Yield, ?Await] Expression[?In, ?Yield, ?Await] , AssignmentExpression[?In, ?Yield, ?Await]

A.3 Statements

Statement[Yield, Await, Return] : BlockStatement[?Yield, ?Await, ?Return] VariableStatement[?Yield, ?Await] EmptyStatement ExpressionStatement[?Yield, ?Await] IfStatement[?Yield, ?Await, ?Return] BreakableStatement[?Yield, ?Await, ?Return] ContinueStatement[?Yield, ?Await] BreakStatement[?Yield, ?Await] [+Return] ReturnStatement[?Yield, ?Await] WithStatement[?Yield, ?Await, ?Return] LabelledStatement[?Yield, ?Await, ?Return] ThrowStatement[?Yield, ?Await] TryStatement[?Yield, ?Await, ?Return] DebuggerStatement Declaration[Yield, Await] : HoistableDeclaration[?Yield, ?Await, ~Default] ClassDeclaration[?Yield, ?Await, ~Default] LexicalDeclaration[+In, ?Yield, ?Await] HoistableDeclaration[Yield, Await, Default] : FunctionDeclaration[?Yield, ?Await, ?Default] GeneratorDeclaration[?Yield, ?Await, ?Default] AsyncFunctionDeclaration[?Yield, ?Await, ?Default] AsyncGeneratorDeclaration[?Yield, ?Await, ?Default] BreakableStatement[Yield, Await, Return] : IterationStatement[?Yield, ?Await, ?Return] SwitchStatement[?Yield, ?Await, ?Return] BlockStatement[Yield, Await, Return] : Block[?Yield, ?Await, ?Return] Block[Yield, Await, Return] : { StatementList[?Yield, ?Await, ?Return]opt } StatementList[Yield, Await, Return] : StatementListItem[?Yield, ?Await, ?Return] StatementList[?Yield, ?Await, ?Return] StatementListItem[?Yield, ?Await, ?Return] StatementListItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] Declaration[?Yield, ?Await] LexicalDeclaration[In, Yield, Await] : LetOrConst BindingList[?In, ?Yield, ?Await] ; LetOrConst : let const BindingList[In, Yield, Await] : LexicalBinding[?In, ?Yield, ?Await] BindingList[?In, ?Yield, ?Await] , LexicalBinding[?In, ?Yield, ?Await] LexicalBinding[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await] VariableStatement[Yield, Await] : var VariableDeclarationList[+In, ?Yield, ?Await] ; VariableDeclarationList[In, Yield, Await] : VariableDeclaration[?In, ?Yield, ?Await] VariableDeclarationList[?In, ?Yield, ?Await] , VariableDeclaration[?In, ?Yield, ?Await] VariableDeclaration[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await] BindingPattern[Yield, Await] : ObjectBindingPattern[?Yield, ?Await] ArrayBindingPattern[?Yield, ?Await] ObjectBindingPattern[Yield, Await] : { } { BindingRestProperty[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] , BindingRestProperty[?Yield, ?Await]opt } ArrayBindingPattern[Yield, Await] : [ Elisionopt BindingRestElement[?Yield, ?Await]opt ] [ BindingElementList[?Yield, ?Await] ] [ BindingElementList[?Yield, ?Await] , Elisionopt BindingRestElement[?Yield, ?Await]opt ] BindingRestProperty[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] BindingPropertyList[Yield, Await] : BindingProperty[?Yield, ?Await] BindingPropertyList[?Yield, ?Await] , BindingProperty[?Yield, ?Await] BindingElementList[Yield, Await] : BindingElisionElement[?Yield, ?Await] BindingElementList[?Yield, ?Await] , BindingElisionElement[?Yield, ?Await] BindingElisionElement[Yield, Await] : Elisionopt BindingElement[?Yield, ?Await] BindingProperty[Yield, Await] : SingleNameBinding[?Yield, ?Await] PropertyName[?Yield, ?Await] : BindingElement[?Yield, ?Await] BindingElement[Yield, Await] : SingleNameBinding[?Yield, ?Await] BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt SingleNameBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt BindingRestElement[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] ... BindingPattern[?Yield, ?Await] EmptyStatement : ; ExpressionStatement[Yield, Await] : [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }] Expression[+In, ?Yield, ?Await] ; IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [lookahead ≠ else] IterationStatement[Yield, Await, Return] : DoWhileStatement[?Yield, ?Await, ?Return] WhileStatement[?Yield, ?Await, ?Return] ForStatement[?Yield, ?Await, ?Return] ForInOfStatement[?Yield, ?Await, ?Return] DoWhileStatement[Yield, Await, Return] : do Statement[?Yield, ?Await, ?Return] while ( Expression[+In, ?Yield, ?Await] ) ; WhileStatement[Yield, Await, Return] : while ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] ForStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] Expression[~In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( var VariableDeclarationList[~In, ?Yield, ?Await] ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( LexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] ForInOfStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] LeftHandSideExpression[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( [lookahead ≠ let] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] ForDeclaration[Yield, Await] : LetOrConst ForBinding[?Yield, ?Await] ForBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] ContinueStatement[Yield, Await] : continue ; continue [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ; BreakStatement[Yield, Await] : break ; break [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ; ReturnStatement[Yield, Await] : return ; return [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; WithStatement[Yield, Await, Return] : with ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] SwitchStatement[Yield, Await, Return] : switch ( Expression[+In, ?Yield, ?Await] ) CaseBlock[?Yield, ?Await, ?Return] CaseBlock[Yield, Await, Return] : { CaseClauses[?Yield, ?Await, ?Return]opt } { CaseClauses[?Yield, ?Await, ?Return]opt DefaultClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return]opt } CaseClauses[Yield, Await, Return] : CaseClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return] CaseClause[?Yield, ?Await, ?Return] CaseClause[Yield, Await, Return] : case Expression[+In, ?Yield, ?Await] : StatementList[?Yield, ?Await, ?Return]opt DefaultClause[Yield, Await, Return] : default : StatementList[?Yield, ?Await, ?Return]opt LabelledStatement[Yield, Await, Return] : LabelIdentifier[?Yield, ?Await] : LabelledItem[?Yield, ?Await, ?Return] LabelledItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] FunctionDeclaration[?Yield, ?Await, ~Default] ThrowStatement[Yield, Await] : throw [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; TryStatement[Yield, Await, Return] : try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] Catch[Yield, Await, Return] : catch ( CatchParameter[?Yield, ?Await] ) Block[?Yield, ?Await, ?Return] catch Block[?Yield, ?Await, ?Return] Finally[Yield, Await, Return] : finally Block[?Yield, ?Await, ?Return] CatchParameter[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] DebuggerStatement : debugger ;

A.4 Functions and Classes

UniqueFormalParameters[Yield, Await] : FormalParameters[?Yield, ?Await] FormalParameters[Yield, Await] : [empty] FunctionRestParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameterList[?Yield, ?Await] , FunctionRestParameter[?Yield, ?Await] FormalParameterList[Yield, Await] : FormalParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameter[?Yield, ?Await] FunctionRestParameter[Yield, Await] : BindingRestElement[?Yield, ?Await] FormalParameter[Yield, Await] : BindingElement[?Yield, ?Await] FunctionDeclaration[Yield, Await, Default] : function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } [+Default] function ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionExpression : function BindingIdentifier[~Yield, ~Await]opt ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionBody[Yield, Await] : FunctionStatementList[?Yield, ?Await] FunctionStatementList[Yield, Await] : StatementList[?Yield, ?Await, +Return]opt ArrowFunction[In, Yield, Await] : ArrowParameters[?Yield, ?Await] [no LineTerminator here] => ConciseBody[?In] ArrowParameters[Yield, Await] : BindingIdentifier[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] ConciseBody[In] : [lookahead ≠ {] ExpressionBody[?In, ~Await] { FunctionBody[~Yield, ~Await] } ExpressionBody[In, Await] : AssignmentExpression[?In, ~Yield, ?Await]

When processing an instance of the production
ArrowParameters[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
the interpretation of CoverParenthesizedExpressionAndArrowParameterList is refined using the following grammar:

ArrowFormalParameters[Yield, Await] : ( UniqueFormalParameters[?Yield, ?Await] )

 

AsyncArrowFunction[In, Yield, Await] : async [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] => AsyncConciseBody[?In] CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In] AsyncConciseBody[In] : [lookahead ≠ {] ExpressionBody[?In, +Await] { AsyncFunctionBody } AsyncArrowBindingIdentifier[Yield] : BindingIdentifier[?Yield, +Await] CoverCallExpressionAndAsyncArrowHead[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

When processing an instance of the production
AsyncArrowFunction[In, Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In]
the interpretation of CoverCallExpressionAndAsyncArrowHead is refined using the following grammar:

AsyncArrowHead : async [no LineTerminator here] ArrowFormalParameters[~Yield, +Await]

 

MethodDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } GeneratorMethod[?Yield, ?Await] AsyncMethod[?Yield, ?Await] AsyncGeneratorMethod[?Yield, ?Await] get ClassElementName[?Yield, ?Await] ( ) { FunctionBody[~Yield, ~Await] } set ClassElementName[?Yield, ?Await] ( PropertySetParameterList ) { FunctionBody[~Yield, ~Await] } PropertySetParameterList : FormalParameter[~Yield, ~Await] GeneratorDeclaration[Yield, Await, Default] : function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } [+Default] function * ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorExpression : function * BindingIdentifier[+Yield, ~Await]opt ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorMethod[Yield, Await] : * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorBody : FunctionBody[+Yield, ~Await] YieldExpression[In, Await] : yield yield [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await] yield [no LineTerminator here] * AssignmentExpression[?In, +Yield, ?Await] AsyncGeneratorDeclaration[Yield, Await, Default] : async [no LineTerminator here] function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } [+Default] async [no LineTerminator here] function * ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorExpression : async [no LineTerminator here] function * BindingIdentifier[+Yield, +Await]opt ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorMethod[Yield, Await] : async [no LineTerminator here] * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorBody : FunctionBody[+Yield, +Await] AsyncFunctionDeclaration[Yield, Await, Default] : async [no LineTerminator here] function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [no LineTerminator here] function ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [no LineTerminator here] function BindingIdentifier[~Yield, +Await]opt ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncMethod[Yield, Await] : async [no LineTerminator here] ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionBody : FunctionBody[~Yield, +Await] AwaitExpression[Yield] : await UnaryExpression[?Yield, +Await] ClassDeclaration[Yield, Await, Default] : class BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await] [+Default] class ClassTail[?Yield, ?Await] ClassExpression[Yield, Await] : class BindingIdentifier[?Yield, ?Await]opt ClassTail[?Yield, ?Await] ClassTail[Yield, Await] : ClassHeritage[?Yield, ?Await]opt { ClassBody[?Yield, ?Await]opt } ClassHeritage[Yield, Await] : extends LeftHandSideExpression[?Yield, ?Await] ClassBody[Yield, Await] : ClassElementList[?Yield, ?Await] ClassElementList[Yield, Await] : ClassElement[?Yield, ?Await] ClassElementList[?Yield, ?Await] ClassElement[?Yield, ?Await] ClassElement[Yield, Await] : MethodDefinition[?Yield, ?Await] static MethodDefinition[?Yield, ?Await] FieldDefinition[?Yield, ?Await] ; static FieldDefinition[?Yield, ?Await] ; ClassStaticBlock ; FieldDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt ClassElementName[Yield, Await] : PropertyName[?Yield, ?Await] PrivateIdentifier ClassStaticBlock : static { ClassStaticBlockBody } ClassStaticBlockBody : ClassStaticBlockStatementList ClassStaticBlockStatementList : StatementList[~Yield, +Await, ~Return]opt

A.5 Scripts and Modules

Script : ScriptBodyopt ScriptBody : StatementList[~Yield, ~Await, ~Return] Module : ModuleBodyopt ModuleBody : ModuleItemList ModuleItemList : ModuleItem ModuleItemList ModuleItem ModuleItem : ImportDeclaration ExportDeclaration StatementListItem[~Yield, +Await, ~Return] ModuleExportName : IdentifierName StringLiteral ImportDeclaration : import ImportClause FromClause ; import ModuleSpecifier ; ImportClause : ImportedDefaultBinding NameSpaceImport NamedImports ImportedDefaultBinding , NameSpaceImport ImportedDefaultBinding , NamedImports ImportedDefaultBinding : ImportedBinding NameSpaceImport : * as ImportedBinding NamedImports : { } { ImportsList } { ImportsList , } FromClause : from ModuleSpecifier ImportsList : ImportSpecifier ImportsList , ImportSpecifier ImportSpecifier : ImportedBinding ModuleExportName as ImportedBinding ModuleSpecifier : StringLiteral ImportedBinding : BindingIdentifier[~Yield, +Await] ExportDeclaration : export ExportFromClause FromClause ; export NamedExports ; export VariableStatement[~Yield, +Await] export Declaration[~Yield, +Await] export default HoistableDeclaration[~Yield, +Await, +Default] export default ClassDeclaration[~Yield, +Await, +Default] export default [lookahead ∉ { function, async [no LineTerminator here] function, class }] AssignmentExpression[+In, ~Yield, +Await] ; ExportFromClause : * * as ModuleExportName NamedExports NamedExports : { } { ExportsList } { ExportsList , } ExportsList : ExportSpecifier ExportsList , ExportSpecifier ExportSpecifier : ModuleExportName ModuleExportName as ModuleExportName

A.6 Number Conversions

StringNumericLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt StrWhiteSpace ::: StrWhiteSpaceChar StrWhiteSpaceopt StrWhiteSpaceChar ::: WhiteSpace LineTerminator StrNumericLiteral ::: StrDecimalLiteral NonDecimalIntegerLiteral[~Sep] StrDecimalLiteral ::: StrUnsignedDecimalLiteral + StrUnsignedDecimalLiteral - StrUnsignedDecimalLiteral StrUnsignedDecimalLiteral ::: Infinity DecimalDigits[~Sep] . DecimalDigits[~Sep]opt ExponentPart[~Sep]opt . DecimalDigits[~Sep] ExponentPart[~Sep]opt DecimalDigits[~Sep] ExponentPart[~Sep]opt

All grammar symbols not explicitly defined by the StringNumericLiteral grammar have the definitions used in the Lexical Grammar for numeric literals.

StringIntegerLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrIntegerLiteral StrWhiteSpaceopt StrIntegerLiteral ::: SignedInteger[~Sep] NonDecimalIntegerLiteral[~Sep]

A.7 Time Zone Offset String Format

UTCOffset ::: TemporalSign Hour TemporalSign Hour HourSubcomponents[+Extended] TemporalSign Hour HourSubcomponents[~Extended] TemporalSign ::: ASCIISign <MINUS> ASCIISign ::: one of + - Hour ::: 0 DecimalDigit 1 DecimalDigit 20 21 22 23 HourSubcomponents[Extended] ::: TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TemporalDecimalFractionopt TimeSeparator[Extended] ::: [+Extended] : [~Extended] [empty] MinuteSecond ::: 0 DecimalDigit 1 DecimalDigit 2 DecimalDigit 3 DecimalDigit 4 DecimalDigit 5 DecimalDigit TemporalDecimalFraction ::: TemporalDecimalSeparator DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator ::: one of . ,

A.8 Regular Expressions

Pattern[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Disjunction[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] | Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: [empty] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Assertion[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Quantifier Assertion[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: ^ $ \b \B (?= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) Quantifier :: QuantifierPrefix QuantifierPrefix ? QuantifierPrefix :: * + ? { DecimalDigits[~Sep] } { DecimalDigits[~Sep] ,} { DecimalDigits[~Sep] , DecimalDigits[~Sep] } Atom[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: PatternCharacter . \ AtomEscape[?UnicodeMode, ?NamedCaptureGroups] CharacterClass[?UnicodeMode, ?UnicodeSetsMode] ( GroupSpecifier[?UnicodeMode]opt Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?: Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) SyntaxCharacter :: one of ^ $ \ . * + ? ( ) [ ] { } | PatternCharacter :: SourceCharacter but not SyntaxCharacter AtomEscape[UnicodeMode, NamedCaptureGroups] :: DecimalEscape CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] [+NamedCaptureGroups] k GroupName[?UnicodeMode] CharacterEscape[UnicodeMode] :: ControlEscape c AsciiLetter 0 [lookahead ∉ DecimalDigit] HexEscapeSequence RegExpUnicodeEscapeSequence[?UnicodeMode] IdentityEscape[?UnicodeMode] ControlEscape :: one of f n r t v GroupSpecifier[UnicodeMode] :: ? GroupName[?UnicodeMode] GroupName[UnicodeMode] :: < RegExpIdentifierName[?UnicodeMode] > RegExpIdentifierName[UnicodeMode] :: RegExpIdentifierStart[?UnicodeMode] RegExpIdentifierName[?UnicodeMode] RegExpIdentifierPart[?UnicodeMode] RegExpIdentifierStart[UnicodeMode] :: IdentifierStartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart[UnicodeMode] :: IdentifierPartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpUnicodeEscapeSequence[UnicodeMode] :: [+UnicodeMode] u HexLeadSurrogate \u HexTrailSurrogate [+UnicodeMode] u HexLeadSurrogate [+UnicodeMode] u HexTrailSurrogate [+UnicodeMode] u HexNonSurrogate [~UnicodeMode] u Hex4Digits [+UnicodeMode] u{ CodePoint } UnicodeLeadSurrogate :: any Unicode code point in the inclusive interval from U+D800 to U+DBFF UnicodeTrailSurrogate :: any Unicode code point in the inclusive interval from U+DC00 to U+DFFF

Each \u HexTrailSurrogate for which the choice of associated u HexLeadSurrogate is ambiguous shall be associated with the nearest possible u HexLeadSurrogate that would otherwise have no corresponding \u HexTrailSurrogate.

 

HexLeadSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xD800 to 0xDBFF HexTrailSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xDC00 to 0xDFFF HexNonSurrogate :: Hex4Digits but only if the MV of Hex4Digits is not in the inclusive interval from 0xD800 to 0xDFFF IdentityEscape[UnicodeMode] :: [+UnicodeMode] SyntaxCharacter [+UnicodeMode] / [~UnicodeMode] SourceCharacter but not UnicodeIDContinue DecimalEscape :: NonZeroDigit DecimalDigits[~Sep]opt [lookahead ∉ DecimalDigit] CharacterClassEscape[UnicodeMode] :: d D s S w W [+UnicodeMode] p{ UnicodePropertyValueExpression } [+UnicodeMode] P{ UnicodePropertyValueExpression } UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue LoneUnicodePropertyNameOrValue UnicodePropertyName :: UnicodePropertyNameCharacters UnicodePropertyNameCharacters :: UnicodePropertyNameCharacter UnicodePropertyNameCharactersopt UnicodePropertyValue :: UnicodePropertyValueCharacters LoneUnicodePropertyNameOrValue :: UnicodePropertyValueCharacters UnicodePropertyValueCharacters :: UnicodePropertyValueCharacter UnicodePropertyValueCharactersopt UnicodePropertyValueCharacter :: UnicodePropertyNameCharacter DecimalDigit UnicodePropertyNameCharacter :: AsciiLetter _ CharacterClass[UnicodeMode, UnicodeSetsMode] :: [ [lookahead ≠ ^] ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] [^ ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] ClassContents[UnicodeMode, UnicodeSetsMode] :: [empty] [~UnicodeSetsMode] NonemptyClassRanges[?UnicodeMode] [+UnicodeSetsMode] ClassSetExpression NonemptyClassRanges[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtom[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtom[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] NonemptyClassRangesNoDash[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] ClassAtom[UnicodeMode] :: - ClassAtomNoDash[?UnicodeMode] ClassAtomNoDash[UnicodeMode] :: SourceCharacter but not one of \ or ] or - \ ClassEscape[?UnicodeMode] ClassEscape[UnicodeMode] :: b [+UnicodeMode] - CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] ClassSetExpression :: ClassUnion ClassIntersection ClassSubtraction ClassUnion :: ClassSetRange ClassUnionopt ClassSetOperand ClassUnionopt ClassIntersection :: ClassSetOperand && [lookahead ≠ &] ClassSetOperand ClassIntersection && [lookahead ≠ &] ClassSetOperand ClassSubtraction :: ClassSetOperand -- ClassSetOperand ClassSubtraction -- ClassSetOperand ClassSetRange :: ClassSetCharacter - ClassSetCharacter ClassSetOperand :: NestedClass ClassStringDisjunction ClassSetCharacter NestedClass :: [ [lookahead ≠ ^] ClassContents[+UnicodeMode, +UnicodeSetsMode] ] [^ ClassContents[+UnicodeMode, +UnicodeSetsMode] ] \ CharacterClassEscape[+UnicodeMode] ClassStringDisjunction :: \q{ ClassStringDisjunctionContents } ClassStringDisjunctionContents :: ClassString ClassString | ClassStringDisjunctionContents ClassString :: [empty] NonEmptyClassString NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt ClassSetCharacter :: [lookahead ∉ ClassSetReservedDoublePunctuator] SourceCharacter but not ClassSetSyntaxCharacter \ CharacterEscape[+UnicodeMode] \ ClassSetReservedPunctuator \b ClassSetReservedDoublePunctuator :: one of && !! ## $$ %% ** ++ ,, .. :: ;; << == >> ?? @@ ^^ `` ~~ ClassSetSyntaxCharacter :: one of ( ) [ ] { } / - \ | ClassSetReservedPunctuator :: one of & - ! # % , : ; < = > @ ` ~

B Additional ECMAScript Features for Web Browsers

The ECMAScript language syntax and semantics defined in this annex are required when the ECMAScript host is a web browser. The content of this annex is normative but optional if the ECMAScript host is not a web browser.

Note

This annex describes various legacy features and other characteristics of web browser ECMAScript hosts. All of the language features and behaviours specified in this annex have one or more undesirable characteristics and in the absence of legacy usage would be removed from this specification. However, the usage of these features by large numbers of existing web pages means that web browsers must continue to support them. The specifications in this annex define the requirements for interoperable implementations of these legacy features.

These features are not considered part of the core ECMAScript language. Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. ECMAScript implementations are discouraged from implementing these features unless the implementation is part of a web browser or is required to run the same legacy ECMAScript code that web browsers encounter.

B.1 Additional Syntax

B.1.1 HTML-like Comments

The syntax and semantics of 12.4 is extended as follows except that this extension is not allowed when parsing source text using the goal symbol Module:

Syntax

InputElementHashbangOrRegExp :: WhiteSpace LineTerminator Comment CommonToken HashbangComment RegularExpressionLiteral HTMLCloseComment Comment :: MultiLineComment SingleLineComment SingleLineHTMLOpenComment SingleLineHTMLCloseComment SingleLineDelimitedComment MultiLineComment :: /* FirstCommentLineopt LineTerminator MultiLineCommentCharsopt */ HTMLCloseCommentopt FirstCommentLine :: SingleLineDelimitedCommentChars SingleLineHTMLOpenComment :: <!-- SingleLineCommentCharsopt SingleLineHTMLCloseComment :: LineTerminatorSequence HTMLCloseComment SingleLineDelimitedComment :: /* SingleLineDelimitedCommentCharsopt */ HTMLCloseComment :: WhiteSpaceSequenceopt SingleLineDelimitedCommentSequenceopt --> SingleLineCommentCharsopt SingleLineDelimitedCommentChars :: SingleLineNotAsteriskChar SingleLineDelimitedCommentCharsopt * SingleLinePostAsteriskCommentCharsopt SingleLineNotAsteriskChar :: SourceCharacter but not one of * or LineTerminator SingleLinePostAsteriskCommentChars :: SingleLineNotForwardSlashOrAsteriskChar SingleLineDelimitedCommentCharsopt * SingleLinePostAsteriskCommentCharsopt SingleLineNotForwardSlashOrAsteriskChar :: SourceCharacter but not one of / or * or LineTerminator WhiteSpaceSequence :: WhiteSpace WhiteSpaceSequenceopt SingleLineDelimitedCommentSequence :: SingleLineDelimitedComment WhiteSpaceSequenceopt SingleLineDelimitedCommentSequenceopt

Similar to a MultiLineComment that contains a line terminator code point, a SingleLineHTMLCloseComment is considered to be a LineTerminator for purposes of parsing by the syntactic grammar.

B.1.2 Regular Expressions Patterns

The syntax of 22.2.1 is modified and extended as follows. These changes introduce ambiguities that are broken by the ordering of grammar productions and by contextual information. When parsing using the following grammar, each alternative is considered only if previous production alternatives do not match.

This alternative pattern grammar and semantics only changes the syntax and semantics of BMP patterns. The following grammar extensions include productions parameterized with the [UnicodeMode] parameter. However, none of these extensions change the syntax of Unicode patterns recognized when parsing with the [UnicodeMode] parameter present on the goal symbol.

Syntax

Term[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: [+UnicodeMode] Assertion[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] [+UnicodeMode] Atom[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Quantifier [+UnicodeMode] Atom[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] [~UnicodeMode] QuantifiableAssertion[?NamedCaptureGroups] Quantifier [~UnicodeMode] Assertion[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] [~UnicodeMode] ExtendedAtom[?NamedCaptureGroups] Quantifier [~UnicodeMode] ExtendedAtom[?NamedCaptureGroups] Assertion[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: ^ $ \b \B [+UnicodeMode] (?= Disjunction[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) [+UnicodeMode] (?! Disjunction[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) [~UnicodeMode] QuantifiableAssertion[?NamedCaptureGroups] (?<= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) QuantifiableAssertion[NamedCaptureGroups] :: (?= Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) (?! Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) ExtendedAtom[NamedCaptureGroups] :: . \ AtomEscape[~UnicodeMode, ?NamedCaptureGroups] \ [lookahead = c] CharacterClass[~UnicodeMode, ~UnicodeSetsMode] ( GroupSpecifier[~UnicodeMode]opt Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) (?: Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) InvalidBracedQuantifier ExtendedPatternCharacter InvalidBracedQuantifier :: { DecimalDigits[~Sep] } { DecimalDigits[~Sep] ,} { DecimalDigits[~Sep] , DecimalDigits[~Sep] } ExtendedPatternCharacter :: SourceCharacter but not one of ^ $ \ . * + ? ( ) [ | AtomEscape[UnicodeMode, NamedCaptureGroups] :: [+UnicodeMode] DecimalEscape [~UnicodeMode] DecimalEscape but only if the CapturingGroupNumber of DecimalEscape is ≤ CountLeftCapturingParensWithin(the Pattern containing DecimalEscape) CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode, ?NamedCaptureGroups] [+NamedCaptureGroups] k GroupName[?UnicodeMode] CharacterEscape[UnicodeMode, NamedCaptureGroups] :: ControlEscape c AsciiLetter 0 [lookahead ∉ DecimalDigit] HexEscapeSequence RegExpUnicodeEscapeSequence[?UnicodeMode] [~UnicodeMode] LegacyOctalEscapeSequence IdentityEscape[?UnicodeMode, ?NamedCaptureGroups] IdentityEscape[UnicodeMode, NamedCaptureGroups] :: [+UnicodeMode] SyntaxCharacter [+UnicodeMode] / [~UnicodeMode] SourceCharacterIdentityEscape[?NamedCaptureGroups] SourceCharacterIdentityEscape[NamedCaptureGroups] :: [~NamedCaptureGroups] SourceCharacter but not c [+NamedCaptureGroups] SourceCharacter but not one of c or k ClassAtomNoDash[UnicodeMode, NamedCaptureGroups] :: SourceCharacter but not one of \ or ] or - \ ClassEscape[?UnicodeMode, ?NamedCaptureGroups] \ [lookahead = c] ClassEscape[UnicodeMode, NamedCaptureGroups] :: b [+UnicodeMode] - [~UnicodeMode] c ClassControlLetter CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode, ?NamedCaptureGroups] ClassControlLetter :: DecimalDigit _ Note

When the same left-hand sides occurs with both [+UnicodeMode] and [~UnicodeMode] guards it is to control the disambiguation priority.

B.1.2.1 Static Semantics: Early Errors

The semantics of 22.2.1.1 is extended as follows:

ExtendedAtom :: InvalidBracedQuantifier
  • It is a Syntax Error if any source text is matched by this production.

Additionally, the rules for the following productions are modified with the addition of the highlighted text:

NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents

B.1.2.2 Static Semantics: CountLeftCapturingParensWithin and CountLeftCapturingParensBefore

In the definitions of CountLeftCapturingParensWithin and CountLeftCapturingParensBefore, references to “ Atom :: ( GroupSpecifieropt Disjunction ) ” are to be interpreted as meaning “ Atom :: ( GroupSpecifieropt Disjunction ) ” or “ ExtendedAtom :: ( GroupSpecifieropt Disjunction ) ”.

B.1.2.3 Static Semantics: IsCharacterClass

The semantics of 22.2.1.5 is extended as follows:

ClassAtomNoDash :: \ [lookahead = c]
  1. Return false.

B.1.2.4 Static Semantics: CharacterValue

The semantics of 22.2.1.6 is extended as follows:

ClassAtomNoDash :: \ [lookahead = c]
  1. Return the numeric value of U+005C (REVERSE SOLIDUS).
ClassEscape :: c ClassControlLetter
  1. Let ch be the code point matched by ClassControlLetter.
  2. Let i be the numeric value of ch.
  3. Return the remainder of dividing i by 32.
CharacterEscape :: LegacyOctalEscapeSequence
  1. Return the MV of LegacyOctalEscapeSequence (see 12.9.4.3).

B.1.2.5 Runtime Semantics: CompileSubpattern

The semantics of CompileSubpattern is extended as follows:

The rule for Term :: QuantifiableAssertion Quantifier is the same as for Term :: Atom Quantifier but with QuantifiableAssertion substituted for Atom.

The rule for Term :: ExtendedAtom Quantifier is the same as for Term :: Atom Quantifier but with ExtendedAtom substituted for Atom.

The rule for Term :: ExtendedAtom is the same as for Term :: Atom but with ExtendedAtom substituted for Atom.

B.1.2.6 Runtime Semantics: CompileAssertion

CompileAssertion rules for the Assertion :: (?= Disjunction ) and Assertion :: (?! Disjunction ) productions are also used for the QuantifiableAssertion productions, but with QuantifiableAssertion substituted for Assertion.

B.1.2.7 Runtime Semantics: CompileAtom

CompileAtom rules for the Atom productions except for Atom :: PatternCharacter are also used for the ExtendedAtom productions, but with ExtendedAtom substituted for Atom. The following rules, with parameter direction, are also added:

ExtendedAtom :: \ [lookahead = c]
  1. Let A be the CharSet containing the single character \ U+005C (REVERSE SOLIDUS).
  2. Return CharacterSetMatcher(rer, A, false, direction).
ExtendedAtom :: ExtendedPatternCharacter
  1. Let ch be the character represented by ExtendedPatternCharacter.
  2. Let A be a one-element CharSet containing the character ch.
  3. Return CharacterSetMatcher(rer, A, false, direction).

B.1.2.8 Runtime Semantics: CompileToCharSet

The semantics of 22.2.2.9 is extended as follows:

The following two rules replace the corresponding rules of CompileToCharSet.

NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents
  1. Let A be CompileToCharSet of the first ClassAtom with argument rer.
  2. Let B be CompileToCharSet of the second ClassAtom with argument rer.
  3. Let C be CompileToCharSet of ClassContents with argument rer.
  4. Let D be CharacterRangeOrUnion(rer, A, B).
  5. Return the union of D and C.
NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents
  1. Let A be CompileToCharSet of ClassAtomNoDash with argument rer.
  2. Let B be CompileToCharSet of ClassAtom with argument rer.
  3. Let C be CompileToCharSet of ClassContents with argument rer.
  4. Let D be CharacterRangeOrUnion(rer, A, B).
  5. Return the union of D and C.

In addition, the following rules are added to CompileToCharSet.

ClassEscape :: c ClassControlLetter
  1. Let cv be the CharacterValue of this ClassEscape.
  2. Let c be the character whose character value is cv.
  3. Return the CharSet containing the single character c.
ClassAtomNoDash :: \ [lookahead = c]
  1. Return the CharSet containing the single character \ U+005C (REVERSE SOLIDUS).
Note
This production can only be reached from the sequence \c within a character class where it is not followed by an acceptable control character.

B.1.2.8.1 CharacterRangeOrUnion ( rer, A, B )

The abstract operation CharacterRangeOrUnion takes arguments rer (a RegExp Record), A (a CharSet), and B (a CharSet) and returns a CharSet. It performs the following steps when called:

  1. If HasEitherUnicodeFlag(rer) is false, then
    1. If A does not contain exactly one character or B does not contain exactly one character, then
      1. Let C be the CharSet containing the single character - U+002D (HYPHEN-MINUS).
      2. Return the union of CharSets A, B and C.
  2. Return CharacterRange(A, B).

B.1.2.9 Static Semantics: ParsePattern ( patternText, u, v )

The semantics of 22.2.3.4 is extended as follows:

The abstract operation ParsePattern takes arguments patternText (a sequence of Unicode code points), u (a Boolean), and v (a Boolean). It performs the following steps when called:

  1. If v is true and u is true, then
    1. Let parseResult be a List containing one or more SyntaxError objects.
  2. Else if v is true, then
    1. Let parseResult be ParseText(patternText, Pattern[+UnicodeMode, +UnicodeSetsMode, +NamedCaptureGroups]).
  3. Else if u is true, then
    1. Let parseResult be ParseText(patternText, Pattern[+UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups]).
  4. Else,
    1. Let parseResult be ParseText(patternText, Pattern[~UnicodeMode, ~UnicodeSetsMode, ~NamedCaptureGroups]).
    2. If parseResult is a Parse Node and parseResult contains a GroupName, then
      1. Set parseResult to ParseText(patternText, Pattern[~UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups]).
  5. Return parseResult.

B.2 Additional Built-in Properties

When the ECMAScript host is a web browser the following additional properties of the standard built-in objects are defined.

B.2.1 Additional Properties of the Global Object

The entries in Table 97 are added to Table 6.

Table 97: Additional Well-known Intrinsic Objects
Intrinsic Name Global Name ECMAScript Language Association
%escape% escape The escape function (B.2.1.1)
%unescape% unescape The unescape function (B.2.1.2)

B.2.1.1 escape ( string )

This function is a property of the global object. It computes a new version of a String value in which certain code units have been replaced by a hexadecimal escape sequence.

When replacing a code unit of numeric value less than or equal to 0x00FF, a two-digit escape sequence of the form %xx is used. When replacing a code unit of numeric value strictly greater than 0x00FF, a four-digit escape sequence of the form %uxxxx is used.

It is the %escape% intrinsic object.

It performs the following steps when called:

  1. Set string to ? ToString(string).
  2. Let len be the length of string.
  3. Let R be the empty String.
  4. Let unescapedSet be the string-concatenation of the ASCII word characters and "@*+-./".
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let C be the code unit at index k within string.
    2. If unescapedSet contains C, then
      1. Let S be C.
    3. Else,
      1. Let n be the numeric value of C.
      2. If n < 256, then
        1. Let hex be the String representation of n, formatted as an uppercase hexadecimal number.
        2. Let S be the string-concatenation of "%" and StringPad(hex, 2, "0", start).
      3. Else,
        1. Let hex be the String representation of n, formatted as an uppercase hexadecimal number.
        2. Let S be the string-concatenation of "%u" and StringPad(hex, 4, "0", start).
    4. Set R to the string-concatenation of R and S.
    5. Set k to k + 1.
  7. Return R.
Note

The encoding is partly based on the encoding described in RFC 1738, but the entire encoding specified in this standard is described above without regard to the contents of RFC 1738. This encoding does not reflect changes to RFC 1738 made by RFC 3986.

B.2.1.2 unescape ( string )

This function is a property of the global object. It computes a new version of a String value in which each escape sequence of the sort that might be introduced by the escape function is replaced with the code unit that it represents.

It is the %unescape% intrinsic object.

It performs the following steps when called:

  1. Set string to ? ToString(string).
  2. Let len be the length of string.
  3. Let R be the empty String.
  4. Let k be 0.
  5. Repeat, while k < len,
    1. Let C be the code unit at index k within string.
    2. If C is the code unit 0x0025 (PERCENT SIGN), then
      1. Let hexDigits be the empty String.
      2. Let optionalAdvance be 0.
      3. If k + 5 < len and the code unit at index k + 1 within string is the code unit 0x0075 (LATIN SMALL LETTER U), then
        1. Set hexDigits to the substring of string from k + 2 to k + 6.
        2. Set optionalAdvance to 5.
      4. Else if k + 3 ≤ len, then
        1. Set hexDigits to the substring of string from k + 1 to k + 3.
        2. Set optionalAdvance to 2.
      5. Let parseResult be ParseText(StringToCodePoints(hexDigits), HexDigits[~Sep]).
      6. If parseResult is a Parse Node, then
        1. Let n be the MV of parseResult.
        2. Set C to the code unit whose numeric value is n.
        3. Set k to k + optionalAdvance.
    3. Set R to the string-concatenation of R and C.
    4. Set k to k + 1.
  6. Return R.

B.2.2 Additional Properties of the String.prototype Object

B.2.2.1 String.prototype.substr ( start, length )

This method returns a substring of the result of converting the this value to a String, starting from index start and running for length code units (or through the end of the String if length is undefined). If start is negative, it is treated as sourceLength + start where sourceLength is the length of the String. The result is a String value, not a String object.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let size be the length of S.
  4. Let intStart be ? ToIntegerOrInfinity(start).
  5. If intStart = -∞, set intStart to 0.
  6. Else if intStart < 0, set intStart to max(size + intStart, 0).
  7. Else, set intStart to min(intStart, size).
  8. If length is undefined, let intLength be size; otherwise let intLength be ? ToIntegerOrInfinity(length).
  9. Set intLength to the result of clamping intLength between 0 and size.
  10. Let intEnd be min(intStart + intLength, size).
  11. Return the substring of S from intStart to intEnd.
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

B.2.2.2 String.prototype.anchor ( name )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "a", "name", name).

B.2.2.2.1 CreateHTML ( string, tag, attribute, value )

The abstract operation CreateHTML takes arguments string (an ECMAScript language value), tag (a String), attribute (a String), and value (an ECMAScript language value) and returns either a normal completion containing a String or a throw completion. It performs the following steps when called:

  1. Let str be ? RequireObjectCoercible(string).
  2. Let S be ? ToString(str).
  3. Let p1 be the string-concatenation of "<" and tag.
  4. If attribute is not the empty String, then
    1. Let V be ? ToString(value).
    2. Let escapedV be the String value that is the same as V except that each occurrence of the code unit 0x0022 (QUOTATION MARK) in V has been replaced with the six code unit sequence "&quot;".
    3. Set p1 to the string-concatenation of:
      • p1
      • the code unit 0x0020 (SPACE)
      • attribute
      • the code unit 0x003D (EQUALS SIGN)
      • the code unit 0x0022 (QUOTATION MARK)
      • escapedV
      • the code unit 0x0022 (QUOTATION MARK)
  5. Let p2 be the string-concatenation of p1 and ">".
  6. Let p3 be the string-concatenation of p2 and S.
  7. Let p4 be the string-concatenation of p3, "</", tag, and ">".
  8. Return p4.

B.2.2.3 String.prototype.big ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "big", "", "").

B.2.2.4 String.prototype.blink ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "blink", "", "").

B.2.2.5 String.prototype.bold ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "b", "", "").

B.2.2.6 String.prototype.fixed ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "tt", "", "").

B.2.2.7 String.prototype.fontcolor ( color )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "font", "color", color).

B.2.2.8 String.prototype.fontsize ( size )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "font", "size", size).

B.2.2.9 String.prototype.italics ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "i", "", "").

B.2.2.10 String.prototype.link ( url )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "a", "href", url).

B.2.2.11 String.prototype.small ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "small", "", "").

B.2.2.12 String.prototype.strike ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "strike", "", "").

B.2.2.13 String.prototype.sub ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "sub", "", "").

B.2.2.14 String.prototype.sup ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "sup", "", "").

B.2.2.15 String.prototype.trimLeft ( )

Note

The property "trimStart" is preferred. The "trimLeft" property is provided principally for compatibility with old code. It is recommended that the "trimStart" property be used in new ECMAScript code.

The initial value of the "trimLeft" property is %String.prototype.trimStart%, defined in 22.1.3.34.

B.2.2.16 String.prototype.trimRight ( )

Note

The property "trimEnd" is preferred. The "trimRight" property is provided principally for compatibility with old code. It is recommended that the "trimEnd" property be used in new ECMAScript code.

The initial value of the "trimRight" property is %String.prototype.trimEnd%, defined in 22.1.3.33.

B.2.3 Additional Properties of the Date.prototype Object

B.2.3.1 Date.prototype.getYear ( )

Note

The getFullYear method is preferred for nearly all purposes, because it avoids the “year 2000 problem.”

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return YearFromTime(LocalTime(t)) - 1900𝔽.

B.2.3.2 Date.prototype.setYear ( year )

Note

The setFullYear method is preferred for nearly all purposes, because it avoids the “year 2000 problem.”

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let y be ? ToNumber(year).
  5. If t is NaN, set t to +0𝔽; otherwise, set t to LocalTime(t).
  6. Let yyyy be MakeFullYear(y).
  7. Let d be MakeDay(yyyy, MonthFromTime(t), DateFromTime(t)).
  8. Let date be MakeDate(d, TimeWithinDay(t)).
  9. Let u be TimeClip(UTC(date)).
  10. Set dateObject.[[DateValue]] to u.
  11. Return u.

B.2.3.3 Date.prototype.toGMTString ( )

Note

The toUTCString method is preferred. This method is provided principally for compatibility with old code.

The initial value of the "toGMTString" property is %Date.prototype.toUTCString%, defined in 21.4.4.43.

B.2.4 Additional Properties of the RegExp.prototype Object

B.2.4.1 RegExp.prototype.compile ( pattern, flags )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[RegExpMatcher]]).
  3. If pattern is an Object and pattern has a [[RegExpMatcher]] internal slot, then
    1. If flags is not undefined, throw a TypeError exception.
    2. Let P be pattern.[[OriginalSource]].
    3. Let F be pattern.[[OriginalFlags]].
  4. Else,
    1. Let P be pattern.
    2. Let F be flags.
  5. Return ? RegExpInitialize(O, P, F).
Note

This method completely reinitializes the this value RegExp with a new pattern and flags. An implementation may interpret use of this method as an assertion that the resulting RegExp object will be used multiple times and hence is a candidate for extra optimization.

B.3 Other Additional Features

B.3.1 Labelled Function Declarations

Prior to ECMAScript 2015, the specification of LabelledStatement did not allow for the association of a statement label with a FunctionDeclaration. However, a labelled FunctionDeclaration was an allowable extension for non-strict code and most browser-hosted ECMAScript implementations supported that extension. In ECMAScript 2015 and later, the grammar production for LabelledStatement permits use of FunctionDeclaration as a LabelledItem but 14.13.1 includes an Early Error rule that produces a Syntax Error if that occurs. That rule is modified with the addition of the highlighted text:

LabelledItem : FunctionDeclaration
  • It is a Syntax Error if any source text that is strict mode code is matched by this production.
Note

The early error rules for WithStatement, IfStatement, and IterationStatement prevent these statements from containing a labelled FunctionDeclaration in non-strict code.

B.3.2 Block-Level Function Declarations Web Legacy Compatibility Semantics

Prior to ECMAScript 2015, the ECMAScript specification did not define the occurrence of a FunctionDeclaration as an element of a Block statement's StatementList. However, support for that form of FunctionDeclaration was an allowable extension and most browser-hosted ECMAScript implementations permitted them. Unfortunately, the semantics of such declarations differ among those implementations. Because of these semantic differences, existing web ECMAScript source text that uses Block level function declarations is only portable among browser implementations if the usage only depends upon the semantic intersection of all of the browser implementations for such declarations. The following are the use cases that fall within that intersection semantics:

  1. A function is declared and only referenced within a single block.

    • One or more FunctionDeclarations whose BindingIdentifier is the name f occur within the function code of an enclosing function g and that declaration is nested within a Block.
    • No other declaration of f that is not a var declaration occurs within the function code of g.
    • All occurrences of f as an IdentifierReference are within the StatementList of the Block containing the declaration of f.
  2. A function is declared and possibly used within a single Block but also referenced by an inner function definition that is not contained within that same Block.

    • One or more FunctionDeclarations whose BindingIdentifier is the name f occur within the function code of an enclosing function g and that declaration is nested within a Block.
    • No other declaration of f that is not a var declaration occurs within the function code of g.
    • There may be occurrences of f as an IdentifierReference within the StatementList of the Block containing the declaration of f.
    • There is at least one occurrence of f as an IdentifierReference within another function h that is nested within g and no other declaration of f shadows the references to f from within h.
    • All invocations of h occur after the declaration of f has been evaluated.
  3. A function is declared and possibly used within a single block but also referenced within subsequent blocks.

    • One or more FunctionDeclaration whose BindingIdentifier is the name f occur within the function code of an enclosing function g and that declaration is nested within a Block.
    • No other declaration of f that is not a var declaration occurs within the function code of g.
    • There may be occurrences of f as an IdentifierReference within the StatementList of the Block containing the declaration of f.
    • There is at least one occurrence of f as an IdentifierReference within the function code of g that lexically follows the Block containing the declaration of f.

The first use case is interoperable with the semantics of Block level function declarations provided by ECMAScript 2015. Any pre-existing ECMAScript source text that employs that use case will operate using the Block level function declarations semantics defined by clauses 10, 14, and 15.

ECMAScript 2015 interoperability for the second and third use cases requires the following extensions to the clause 10, clause 15, clause 19.2.1 and clause 16.1.7 semantics.

If an ECMAScript implementation has a mechanism for reporting diagnostic warning messages, a warning should be produced when code contains a FunctionDeclaration for which these compatibility semantics are applied and introduce observable differences from non-compatibility semantics. For example, if a var binding is not introduced because its introduction would create an early error, a warning message should not be produced.

B.3.2.1 Changes to FunctionDeclarationInstantiation

During FunctionDeclarationInstantiation the following steps are performed in place of step 29:

  1. If strict is false, then
    1. For each FunctionDeclaration f that is directly contained in the StatementList of a Block, CaseClause, or DefaultClause, do
      1. Let F be StringValue of the BindingIdentifier of f.
      2. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for func and parameterNames does not contain F, then
        1. NOTE: A var binding for F is only instantiated here if it is neither a VarDeclaredName, the name of a formal parameter, or another FunctionDeclaration.
        2. If instantiatedVarNames does not contain F and F is not "arguments", then
          1. Perform ! varEnv.CreateMutableBinding(F, false).
          2. Perform ! varEnv.InitializeBinding(F, undefined).
          3. Append F to instantiatedVarNames.
        3. When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6:
          1. Let fenv be the running execution context's VariableEnvironment.
          2. Let benv be the running execution context's LexicalEnvironment.
          3. Let fobj be ! benv.GetBindingValue(F, false).
          4. Perform ! fenv.SetMutableBinding(F, fobj, false).
          5. Return unused.

B.3.2.2 Changes to GlobalDeclarationInstantiation

During GlobalDeclarationInstantiation the following steps are performed in place of step 12:

  1. Perform the following steps:
    1. Let strict be IsStrict of script.
    2. If strict is false, then
      1. Let declaredFunctionOrVarNames be the list-concatenation of declaredFunctionNames and declaredVarNames.
      2. For each FunctionDeclaration f that is directly contained in the StatementList of a Block, CaseClause, or DefaultClause Contained within script, do
        1. Let F be StringValue of the BindingIdentifier of f.
        2. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for script, then
          1. If env.HasLexicalDeclaration(F) is false, then
            1. Let fnDefinable be ? env.CanDeclareGlobalVar(F).
            2. If fnDefinable is true, then
              1. NOTE: A var binding for F is only instantiated here if it is neither a VarDeclaredName nor the name of another FunctionDeclaration.
              2. If declaredFunctionOrVarNames does not contain F, then
                1. Perform ? env.CreateGlobalVarBinding(F, false).
                2. Append F to declaredFunctionOrVarNames.
              3. When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6:
                1. Let genv be the running execution context's VariableEnvironment.
                2. Let benv be the running execution context's LexicalEnvironment.
                3. Let fobj be ! benv.GetBindingValue(F, false).
                4. Perform ? genv.SetMutableBinding(F, fobj, false).
                5. Return unused.

B.3.2.3 Changes to EvalDeclarationInstantiation

During EvalDeclarationInstantiation the following steps are performed in place of step 13:

  1. If strict is false, then
    1. Let declaredFunctionOrVarNames be the list-concatenation of declaredFunctionNames and declaredVarNames.
    2. For each FunctionDeclaration f that is directly contained in the StatementList of a Block, CaseClause, or DefaultClause Contained within body, do
      1. Let F be StringValue of the BindingIdentifier of f.
      2. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for body, then
        1. Let bindingExists be false.
        2. Let thisEnv be lexEnv.
        3. Assert: The following loop will terminate.
        4. Repeat, while thisEnv is not varEnv,
          1. If thisEnv is not an Object Environment Record, then
            1. If ! thisEnv.HasBinding(F) is true, then
              1. Let bindingExists be true.
          2. Set thisEnv to thisEnv.[[OuterEnv]].
        5. If bindingExists is false and varEnv is a Global Environment Record, then
          1. If varEnv.HasLexicalDeclaration(F) is false, then
            1. Let fnDefinable be ? varEnv.CanDeclareGlobalVar(F).
          2. Else,
            1. Let fnDefinable be false.
        6. Else,
          1. Let fnDefinable be true.
        7. If bindingExists is false and fnDefinable is true, then
          1. If declaredFunctionOrVarNames does not contain F, then
            1. If varEnv is a Global Environment Record, then
              1. Perform ? varEnv.CreateGlobalVarBinding(F, true).
            2. Else,
              1. Let bindingExists be ! varEnv.HasBinding(F).
              2. If bindingExists is false, then
                1. Perform ! varEnv.CreateMutableBinding(F, true).
                2. Perform ! varEnv.InitializeBinding(F, undefined).
            3. Append F to declaredFunctionOrVarNames.
          2. When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6:
            1. Let genv be the running execution context's VariableEnvironment.
            2. Let benv be the running execution context's LexicalEnvironment.
            3. Let fobj be ! benv.GetBindingValue(F, false).
            4. Perform ? genv.SetMutableBinding(F, fobj, false).
            5. Return unused.

B.3.2.4 Changes to Block Static Semantics: Early Errors

The rules for the following production in 14.2.1 are modified with the addition of the highlighted text:

Block : { StatementList }

B.3.2.5 Changes to switch Statement Static Semantics: Early Errors

The rules for the following production in 14.12.1 are modified with the addition of the highlighted text:

SwitchStatement : switch ( Expression ) CaseBlock

B.3.2.6 Changes to BlockDeclarationInstantiation

During BlockDeclarationInstantiation the following steps are performed in place of step 3.a.ii.1:

  1. If ! env.HasBinding(dn) is false, then
    1. Perform ! env.CreateMutableBinding(dn, false).

During BlockDeclarationInstantiation the following steps are performed in place of step 3.b.iii:

  1. Perform the following steps:
    1. If the binding for fn in env is an uninitialized binding, then
      1. Perform ! env.InitializeBinding(fn, fo).
    2. Else,
      1. Assert: d is a FunctionDeclaration.
      2. Perform ! env.SetMutableBinding(fn, fo, false).

B.3.3 FunctionDeclarations in IfStatement Statement Clauses

The following augments the IfStatement production in 14.6:

IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else FunctionDeclaration[?Yield, ?Await, ~Default] if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else FunctionDeclaration[?Yield, ?Await, ~Default] if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] [lookahead ≠ else]

This production only applies when parsing non-strict code. Source text matched by this production is processed as if each matching occurrence of FunctionDeclaration[?Yield, ?Await, ~Default] was the sole StatementListItem of a BlockStatement occupying that position in the source text. The semantics of such a synthetic BlockStatement includes the web legacy compatibility semantics specified in B.3.2.

B.3.4 VariableStatements in Catch Blocks

The content of subclause 14.15.1 is replaced with the following:

Catch : catch ( CatchParameter ) Block Note

The Block of a Catch clause may contain var declarations that bind a name that is also bound by the CatchParameter. At runtime, such bindings are instantiated in the VariableDeclarationEnvironment. They do not shadow the same-named bindings introduced by the CatchParameter and hence the Initializer for such var declarations will assign to the corresponding catch parameter rather than the var binding.

This modified behaviour also applies to var and function declarations introduced by direct eval calls contained within the Block of a Catch clause. This change is accomplished by modifying the algorithm of 19.2.1.3 as follows:

Step 3.d.i.2.a.i is replaced by:

  1. If thisEnv is not the Environment Record for a Catch clause, throw a SyntaxError exception.

Step 13.b.ii.4.a.i.i is replaced by:

  1. If thisEnv is not the Environment Record for a Catch clause, let bindingExists be true.

B.3.5 Initializers in ForIn Statement Heads

The following augments the ForInOfStatement production in 14.7.5:

ForInOfStatement[Yield, Await, Return] : for ( var BindingIdentifier[?Yield, ?Await] Initializer[~In, ?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]

This production only applies when parsing non-strict code.

The static semantics of ContainsDuplicateLabels in 8.3.1 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Return ContainsDuplicateLabels of Statement with argument labelSet.

The static semantics of ContainsUndefinedBreakTarget in 8.3.2 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Return ContainsUndefinedBreakTarget of Statement with argument labelSet.

The static semantics of ContainsUndefinedContinueTarget in 8.3.3 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Return ContainsUndefinedContinueTarget of Statement with arguments iterationSet and « ».

The static semantics of IsDestructuring in 14.7.5.2 are augmented with the following:

BindingIdentifier : Identifier yield await
  1. Return false.

The static semantics of VarDeclaredNames in 8.2.6 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Let names1 be the BoundNames of BindingIdentifier.
  2. Let names2 be the VarDeclaredNames of Statement.
  3. Return the list-concatenation of names1 and names2.

The static semantics of VarScopedDeclarations in 8.2.7 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Let declarations1 be « BindingIdentifier ».
  2. Let declarations2 be the VarScopedDeclarations of Statement.
  3. Return the list-concatenation of declarations1 and declarations2.

The runtime semantics of ForInOfLoopEvaluation in 14.7.5.5 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Let bindingId be StringValue of BindingIdentifier.
  2. Let lhs be ? ResolveBinding(bindingId).
  3. If IsAnonymousFunctionDefinition(Initializer) is true, then
    1. Let value be ? NamedEvaluation of Initializer with argument bindingId.
  4. Else,
    1. Let rhs be ? Evaluation of Initializer.
    2. Let value be ? GetValue(rhs).
  5. Perform ? PutValue(lhs, value).
  6. Let keyResult be ? ForIn/OfHeadEvaluation(« », Expression, enumerate).
  7. Return ? ForIn/OfBodyEvaluation(BindingIdentifier, Statement, keyResult, enumerate, var-binding, labelSet).

B.3.6 The [[IsHTMLDDA]] Internal Slot

An [[IsHTMLDDA]] internal slot may exist on host-defined objects. Objects with an [[IsHTMLDDA]] internal slot behave like undefined in the ToBoolean and IsLooselyEqual abstract operations and when used as an operand for the typeof operator.

Note

Objects with an [[IsHTMLDDA]] internal slot are never created by this specification. However, the document.all object in web browsers is a host-defined exotic object with this slot that exists for web compatibility purposes. There are no other known examples of this type of object and implementations should not create any with the exception of document.all.

B.3.6.1 Changes to ToBoolean

The following step replaces step 3 of ToBoolean:

  1. If argument is an Object and argument has an [[IsHTMLDDA]] internal slot, return false.

B.3.6.2 Changes to IsLooselyEqual

The following steps replace step 4 of IsLooselyEqual:

  1. Perform the following steps:
    1. If x is an Object, x has an [[IsHTMLDDA]] internal slot, and y is either undefined or null, return true.
    2. If x is either undefined or null, y is an Object, and y has an [[IsHTMLDDA]] internal slot, return true.

B.3.6.3 Changes to the typeof Operator

The following step replaces step 12 of the evaluation semantics for typeof:

  1. If val has an [[IsHTMLDDA]] internal slot, return "undefined".

B.3.7 Non-default behaviour in HostMakeJobCallback

The HostMakeJobCallback abstract operation allows hosts which are web browsers to specify non-default behaviour.

B.3.8 Non-default behaviour in HostEnsureCanAddPrivateElement

The HostEnsureCanAddPrivateElement abstract operation allows hosts which are web browsers to specify non-default behaviour.

C The Strict Mode of ECMAScript

The strict mode restriction and exceptions

D Host Layering Points

See 4.2 for the definition of host.

D.1 Host Hooks

HostCallJobCallback(...)

HostEnqueueFinalizationRegistryCleanupJob(...)

HostEnqueueGenericJob(...)

HostEnqueuePromiseJob(...)

HostEnqueueTimeoutJob(...)

HostEnsureCanCompileStrings(...)

HostFinalizeImportMeta(...)

HostGetImportMetaProperties(...)

HostGrowSharedArrayBuffer(...)

HostHasSourceTextAvailable(...)

HostLoadImportedModule(...)

HostMakeJobCallback(...)

HostPromiseRejectionTracker(...)

HostResizeArrayBuffer(...)

InitializeHostDefinedRealm(...)

D.2 Host-defined Fields

[[HostDefined]] on Realm Records: See Table 24.

[[HostDefined]] on Script Records: See Table 40.

[[HostDefined]] on Module Records: See Table 41.

[[HostDefined]] on JobCallback Records: See Table 28.

[[HostSynchronizesWith]] on Candidate Executions: See Table 96.

[[IsHTMLDDA]]: See B.3.6.

D.3 Host-defined Objects

The global object: See clause 19.

D.4 Running Jobs

Preparation steps before, and cleanup steps after, invocation of Job Abstract Closures. See 9.5.

D.5 Internal Methods of Exotic Objects

Any of the essential internal methods in Table 4 for any exotic object not specified within this specification.

D.6 Built-in Objects and Methods

Any built-in objects and methods not defined within this specification, except as restricted in 17.1.

E Corrections and Clarifications in ECMAScript 2015 with Possible Compatibility Impact

9.1.1.4.15-9.1.1.4.18 Edition 5 and 5.1 used a property existence test to determine whether a global object property corresponding to a new global declaration already existed. ECMAScript 2015 uses an own property existence test. This corresponds to what has been most commonly implemented by web browsers.

10.4.2.1: The 5th Edition moved the capture of the current array length prior to the integer conversion of the array index or new length value. However, the captured length value could become invalid if the conversion process has the side-effect of changing the array length. ECMAScript 2015 specifies that the current array length must be captured after the possible occurrence of such side-effects.

21.4.1.31: Previous editions permitted the TimeClip abstract operation to return either +0𝔽 or -0𝔽 as the representation of a 0 time value. ECMAScript 2015 specifies that +0𝔽 always returned. This means that for ECMAScript 2015 the time value of a Date is never observably -0𝔽 and methods that return time values never return -0𝔽.

21.4.1.32: If a UTC offset representation is not present, the local time zone is used. Edition 5.1 incorrectly stated that a missing time zone should be interpreted as "z".

21.4.4.36: If the year cannot be represented using the Date Time String Format specified in 21.4.1.32 a RangeError exception is thrown. Previous editions did not specify the behaviour for that case.

21.4.4.41: Previous editions did not specify the value returned by Date.prototype.toString when the time value is NaN. ECMAScript 2015 specifies the result to be the String value "Invalid Date".

22.2.4.1, 22.2.6.13.1: Any LineTerminator code points in the value of the "source" property of a RegExp instance must be expressed using an escape sequence. Edition 5.1 only required the escaping of /.

22.2.6.8, 22.2.6.11: In previous editions, the specifications for String.prototype.match and String.prototype.replace was incorrect for cases where the pattern argument was a RegExp value whose global flag is set. The previous specifications stated that for each attempt to match the pattern, if lastIndex did not change, it should be incremented by 1. The correct behaviour is that lastIndex should be incremented by 1 only if the pattern matched the empty String.

23.1.3.30: Previous editions did not specify how a NaN value returned by a comparefn was interpreted by Array.prototype.sort. ECMAScript 2015 specifies that such as value is treated as if +0𝔽 was returned from the comparefn. ECMAScript 2015 also specifies that ToNumber is applied to the result returned by a comparefn. In previous editions, the effect of a comparefn result that is not a Number value was implementation-defined. In practice, implementations call ToNumber.

F Additions and Changes That Introduce Incompatibilities with Prior Editions

6.2.5: In ECMAScript 2015, Function calls are not allowed to return a Reference Record.

7.1.4.1: In ECMAScript 2015, ToNumber applied to a String value now recognizes and converts BinaryIntegerLiteral and OctalIntegerLiteral numeric strings. In previous editions such strings were converted to NaN.

9.3: In ECMAScript 2018, Template objects are canonicalized based on Parse Node (source location), instead of across all occurrences of that template literal or tagged template in a Realm in previous editions.

12.2: In ECMAScript 2016, Unicode 8.0.0 or higher is mandated, as opposed to ECMAScript 2015 which mandated Unicode 5.1. In particular, this caused U+180E MONGOLIAN VOWEL SEPARATOR, which was in the Space_Separator (Zs) category and thus treated as whitespace in ECMAScript 2015, to be moved to the Format (Cf) category (as of Unicode 6.3.0). This causes whitespace-sensitive methods to behave differently. For example, "\u180E".trim().length was 0 in previous editions, but 1 in ECMAScript 2016 and later. Additionally, ECMAScript 2017 mandated always using the latest version of the Unicode Standard.

12.7: In ECMAScript 2015, the valid code points for an IdentifierName are specified in terms of the Unicode properties “ID_Start” and “ID_Continue”. In previous editions, the valid IdentifierName or Identifier code points were specified by enumerating various Unicode code point categories.

12.10.1: In ECMAScript 2015, Automatic Semicolon Insertion adds a semicolon at the end of a do-while statement if the semicolon is missing. This change aligns the specification with the actual behaviour of most existing implementations.

13.2.5.1: In ECMAScript 2015, it is no longer an early error to have duplicate property names in Object Initializers.

13.15.1: In ECMAScript 2015, strict mode code containing an assignment to an immutable binding such as the function name of a FunctionExpression does not produce an early error. Instead it produces a runtime error.

14.2: In ECMAScript 2015, a StatementList beginning with the token let followed by the input elements LineTerminator then Identifier is the start of a LexicalDeclaration. In previous editions, automatic semicolon insertion would always insert a semicolon before the Identifier input element.

14.5: In ECMAScript 2015, a StatementListItem beginning with the token let followed by the token [ is the start of a LexicalDeclaration. In previous editions such a sequence would be the start of an ExpressionStatement.

14.6.2: In ECMAScript 2015, the normal result of an IfStatement is never the value empty. If no Statement part is evaluated or if the evaluated Statement part produces a normal completion containing empty, the result of the IfStatement is undefined.

14.7: In ECMAScript 2015, if the ( token of a for statement is immediately followed by the token sequence let [ then the let is treated as the start of a LexicalDeclaration. In previous editions such a token sequence would be the start of an Expression.

14.7: In ECMAScript 2015, if the ( token of a for-in statement is immediately followed by the token sequence let [ then the let is treated as the start of a ForDeclaration. In previous editions such a token sequence would be the start of an LeftHandSideExpression.

14.7: Prior to ECMAScript 2015, an initialization expression could appear as part of the VariableDeclaration that precedes the in keyword. In ECMAScript 2015, the ForBinding in that same position does not allow the occurrence of such an initializer. In ECMAScript 2017, such an initializer is permitted only in non-strict code.

14.7: In ECMAScript 2015, the result of evaluating an IterationStatement is never a normal completion whose [[Value]] is empty. If the Statement part of an IterationStatement is not evaluated or if the final evaluation of the Statement part produces a normal completion whose [[Value]] is empty, the result of evaluating the IterationStatement is a normal completion whose [[Value]] is undefined.

14.11.2: In ECMAScript 2015, the result of evaluating a WithStatement is never a normal completion whose [[Value]] is empty. If evaluation of the Statement part of a WithStatement produces a normal completion whose [[Value]] is empty, the result of evaluating the WithStatement is a normal completion whose [[Value]] is undefined.

14.12.4: In ECMAScript 2015, the result of evaluating a SwitchStatement is never a normal completion whose [[Value]] is empty. If evaluation of the CaseBlock part of a SwitchStatement produces a normal completion whose [[Value]] is empty, the result of evaluating the SwitchStatement is a normal completion whose [[Value]] is undefined.

14.15: In ECMAScript 2015, it is an early error for a Catch clause to contain a var declaration for the same Identifier that appears as the Catch clause parameter. In previous editions, such a variable declaration would be instantiated in the enclosing variable environment but the declaration's Initializer value would be assigned to the Catch parameter.

14.15, 19.2.1.3: In ECMAScript 2015, a runtime SyntaxError is thrown if a Catch clause evaluates a non-strict direct eval whose eval code includes a var or FunctionDeclaration declaration that binds the same Identifier that appears as the Catch clause parameter.

14.15.3: In ECMAScript 2015, the result of a TryStatement is never the value empty. If the Block part of a TryStatement evaluates to a normal completion containing empty, the result of the TryStatement is undefined. If the Block part of a TryStatement evaluates to a throw completion and it has a Catch part that evaluates to a normal completion containing empty, the result of the TryStatement is undefined if there is no Finally clause or if its Finally clause evaluates to an empty normal completion.

15.4.5 In ECMAScript 2015, the function objects that are created as the values of the [[Get]] or [[Set]] attribute of accessor properties in an ObjectLiteral are not constructor functions and they do not have a "prototype" own property. In the previous edition, they were constructors and had a "prototype" property.

20.1.2.6: In ECMAScript 2015, if the argument to Object.freeze is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.8: In ECMAScript 2015, if the argument to Object.getOwnPropertyDescriptor is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.10: In ECMAScript 2015, if the argument to Object.getOwnPropertyNames is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.12: In ECMAScript 2015, if the argument to Object.getPrototypeOf is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.16: In ECMAScript 2015, if the argument to Object.isExtensible is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.17: In ECMAScript 2015, if the argument to Object.isFrozen is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.18: In ECMAScript 2015, if the argument to Object.isSealed is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.19: In ECMAScript 2015, if the argument to Object.keys is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.20: In ECMAScript 2015, if the argument to Object.preventExtensions is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.22: In ECMAScript 2015, if the argument to Object.seal is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.2.3.2: In ECMAScript 2015, the [[Prototype]] internal slot of a bound function is set to the [[GetPrototypeOf]] value of its target function. In the previous edition, [[Prototype]] was always set to %Function.prototype%.

20.2.4.1: In ECMAScript 2015, the "length" property of function instances is configurable. In previous editions it was non-configurable.

20.5.6.2: In ECMAScript 2015, the [[Prototype]] internal slot of a NativeError constructor is the Error constructor. In previous editions it was the Function prototype object.

21.4.4 In ECMAScript 2015, the Date prototype object is not a Date instance. In previous editions it was a Date instance whose TimeValue was NaN.

22.1.3.12 In ECMAScript 2015, the String.prototype.localeCompare function must treat Strings that are canonically equivalent according to the Unicode Standard as being identical. In previous editions implementations were permitted to ignore canonical equivalence and could instead use a bit-wise comparison.

22.1.3.28 and 22.1.3.30 In ECMAScript 2015, lowercase/upper conversion processing operates on code points. In previous editions such the conversion processing was only applied to individual code units. The only affected code points are those in the Deseret block of Unicode.

22.1.3.32 In ECMAScript 2015, the String.prototype.trim method is defined to recognize white space code points that may exist outside of the Unicode BMP. However, as of Unicode 7 no such code points are defined. In previous editions such code points would not have been recognized as white space.

22.2.4.1 In ECMAScript 2015, If the pattern argument is a RegExp instance and the flags argument is not undefined, a new RegExp instance is created just like pattern except that pattern's flags are replaced by the argument flags. In previous editions a TypeError exception was thrown when pattern was a RegExp instance and flags was not undefined.

22.2.6 In ECMAScript 2015, the RegExp prototype object is not a RegExp instance. In previous editions it was a RegExp instance whose pattern is the empty String.

22.2.6 In ECMAScript 2015, "source", "global", "ignoreCase", and "multiline" are accessor properties defined on the RegExp prototype object. In previous editions they were data properties defined on RegExp instances.

25.4.15: In ECMAScript 2019, Atomics.wake has been renamed to Atomics.notify to prevent confusion with Atomics.wait.

27.1.4.4, 27.6.3.6: In ECMAScript 2019, the number of Jobs enqueued by await was reduced, which could create an observable difference in resolution order between a then() call and an await expression.

G Colophon

This specification is authored on GitHub in a plaintext source format called Ecmarkup. Ecmarkup is an HTML and Markdown dialect that provides a framework and toolset for authoring ECMAScript specifications in plaintext and processing the specification into a full-featured HTML rendering that follows the editorial conventions for this document. Ecmarkup builds on and integrates a number of other formats and technologies including Grammarkdown for defining syntax and Ecmarkdown for authoring algorithm steps. PDF renderings of this specification are produced by printing the HTML rendering to a PDF.

Prior editions of this specification were authored using Word—the Ecmarkup source text that formed the basis of this edition was produced by converting the ECMAScript 2015 Word document to Ecmarkup using an automated conversion tool.

H Bibliography

  1. IEEE 754-2019: IEEE Standard for Floating-Point Arithmetic. Institute of Electrical and Electronic Engineers, New York (2019) Note

    There are no normative changes between IEEE 754-2008 and IEEE 754-2019 that affect the ECMA-262 specification.

  2. The Unicode Standard, available at <https://unicode.org/versions/latest>
  3. Unicode Technical Note #5: Canonical Equivalence in Applications, available at <https://unicode.org/notes/tn5/>
  4. Unicode Technical Standard #10: Unicode Collation Algorithm, available at <https://unicode.org/reports/tr10/>
  5. Unicode Standard Annex #15, Unicode Normalization Forms, available at <https://unicode.org/reports/tr15/>
  6. Unicode Standard Annex #18: Unicode Regular Expressions, available at <https://unicode.org/reports/tr18/>
  7. Unicode Standard Annex #24: Unicode Script Property, available at <https://unicode.org/reports/tr24/>
  8. Unicode Standard Annex #31, Unicode Identifiers and Pattern Syntax, available at <https://unicode.org/reports/tr31/>
  9. Unicode Standard Annex #44: Unicode Character Database, available at <https://unicode.org/reports/tr44/>
  10. Unicode Technical Standard #51: Unicode Emoji, available at <https://unicode.org/reports/tr51/>
  11. IANA Time Zone Database, available at <https://www.iana.org/time-zones>
  12. ISO 8601:2004(E) Data elements and interchange formats — Information interchange — Representation of dates and times
  13. RFC 1738 “Uniform Resource Locators (URL)”, available at <https://tools.ietf.org/html/rfc1738>
  14. RFC 2396 “Uniform Resource Identifiers (URI): Generic Syntax”, available at <https://tools.ietf.org/html/rfc2396>
  15. RFC 3629 “UTF-8, a transformation format of ISO 10646”, available at <https://tools.ietf.org/html/rfc3629>
  16. RFC 7231 “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content”, available at <https://tools.ietf.org/html/rfc7231>

I Copyright & Software License

Ecma International

Rue du Rhone 114

CH-1204 Geneva

Tel: +41 22 849 6000

Fax: +41 22 849 6001

Web: https://ecma-international.org/

Copyright Notice

© 2024 Ecma International

By obtaining and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions.

Permission under Ecma’s copyright to copy, modify, prepare derivative works of, and distribute this work, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the work or portions thereof, including modifications:

  1. (i) The full text of this COPYRIGHT NOTICE AND COPYRIGHT LICENSE in a location viewable to users of the redistributed or derivative work.
  2. (ii) Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the Ecma alternative copyright notice should be included.
  3. (iii) Notice of any changes or modifications, through a copyright statement on the document such as “This document includes material copied from or derived from [title and URI of the Ecma document]. Copyright © Ecma International.”

Disclaimers

THIS WORK IS PROVIDED “AS IS,” AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE DOCUMENT WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.

COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT.

The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the work without specific, written prior permission. Title to copyright in this work will at all times remain with copyright holders.

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Syntax-Directed Operations
Permalink Pin References (0)